java program

 

Use the code from the book (and from my notes) to implement a Stack ADT using a linked list.( https://github.com/IvoIvanov77/-Algorithms/blob/403289d0c471f157049d3279bbfe5917de69b4df/src/fundamentals/Evaluate.java ) Use this Stack to implement Dijkstra’s Two-Stack Algorithm for expression evaluation. This code is also given in the book and in my notes. You will need to change this code so that the algorithm is in a separate method for the evaluation. That is, read the input into a String variable that you pass to your method for evaluation.

Don't use plagiarized sources. Get Your Custom Essay on
java program
Just from $13/Page
Order Essay

To this code, add Junit test to test the Stack methods and to test the evaluate method.

META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 1.8.0_222 (Oracle Corporation)

COPYING
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program–to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers’ and authors’ protection, the GPL clearly explains
that there is no warranty for this free software. For both users’ and
authors’ sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users’ freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this
License. Each licensee is addressed as “you”. “Licensees” and
“recipients” may be individuals or organizations.
To “modify” a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a “modified version” of the
earlier work or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based
on the Program.
To “propagate” a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To “convey” a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices”
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work
for making modifications to it. “Object code” means any non-source
form of a work.
A “Standard Interface” means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The “System Libraries” of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
“Major Component”, in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work’s
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work’s
users, your or third parties’ legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program’s source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
“keep intact all notices”.
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
“aggregate” if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation’s users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A “User Product” is either (1) a “consumer product”, which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, “normally used” refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
“Installation Information” for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered “further
restrictions” within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An “entity transaction” is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party’s predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor’s “contributor version”.
A contributor’s “essential patent claims” are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, “control” includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor’s essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a “patent license” is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To “grant” such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. “Knowingly relying” means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient’s use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is “discriminatory” if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others’ Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License “or any later version” applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy’s
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the “copyright” line and a pointer to where the full notice is found.

Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode: Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w’.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c’ for details.
The hypothetical commands `show w’ and `show c’ should show the appropriate
parts of the General Public License. Of course, your program’s commands
might be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a “copyright disclaimer” for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.

edu/princeton/cs/algs4/Accumulator.java
edu/princeton/cs/algs4/Accumulator.java
/******************************************************************************

 *  Compilation:  javac Accumulator.java

 *  Execution:    java Accumulator < input.txt  *  Dependencies: StdOut.java StdIn.java  *  *  Mutable data type that calculates the mean, sample standard  *  deviation, and sample variance of a stream of real numbers  *  use a stable, one-pass algorithm.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Accumulator} class is a data type for computing the running  *  mean, sample standard deviation, and sample variance of a stream of real  *  numbers. It provides an example of a mutable data type and a streaming  *  algorithm.  *  

 *  This implementation uses a one-pass algorithm that is less susceptible

 *  to floating-point roundoff error than the more straightforward

 *  implementation based on saving the sum of the squares of the numbers.

 *  This technique is due to

 *  B. P. Welford.

 *  Each operation takes constant time in the worst case.

 *  The amount of memory is constant – the data values are not stored.

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Accumulator
 
{

    
private
 
int
 n 
=
 
0
;
          
// number of data values

    
private
 
double
 sum 
=
 
0.0
;
   
// sample variance * (n-1)

    
private
 
double
 mu 
=
 
0.0
;
    
// sample mean

    
/**

     * Initializes an accumulator.

     */

    
public
 
Accumulator
()
 
{

    
}

    
/**

     * Adds the specified data value to the accumulator.

     * 
@param
  x the data value

     */

    
public
 
void
 addDataValue
(
double
 x
)
 
{

        n
++
;

        
double
 delta 
=
 x 

 mu
;

        mu  
+=
 delta 
/
 n
;

        sum 
+=
 
(
double
)
 
(


 
1
)
 
/
 n 
*
 delta 
*
 delta
;

    
}

    
/**

     * Returns the mean of the data values.

     * 
@return
 the mean of the data values

     */

    
public
 
double
 mean
()
 
{

        
return
 mu
;

    
}

    
/**

     * Returns the sample variance of the data values.

     * 
@return
 the sample variance of the data values

     */

    
public
 
double
 var
()
 
{

        
if
 
(

<=   1 )   return   Double . NaN ;          return  sum  /   ( n  -   1 );      }      /**      * Returns the sample standard deviation of the data values.      *  @return  the sample standard deviation of the data values      */      public   double  stddev ()   {          return   Math . sqrt ( this . var ());      }      /**      * Returns the number of data values.      *  @return  the number of data values      */      public   int  count ()   {          return  n ;      }      /**      * Returns a string representation of this accumulator.      *  @return  a string representation of this accumulator      */      public   String  toString ()   {          return   "n = "   +  n  +   ", mean = "   +  mean ()   +   ", stddev = "   +  stddev ();      }      /**      * Unit tests the { @code  Accumulator} data type.      * Reads in a stream of real number from standard input;      * adds them to the accumulator; and prints the mean,      * sample standard deviation, and sample variance to standard      * output.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          Accumulator  stats  =   new   Accumulator ();          while   ( ! StdIn . isEmpty ())   {              double  x  =   StdIn . readDouble ();             stats . addDataValue ( x );          }          StdOut . printf ( "n      = %d\n" ,    stats . count ());          StdOut . printf ( "mean   = %.5f\n" ,  stats . mean ());          StdOut . printf ( "stddev = %.5f\n" ,  stats . stddev ());          StdOut . printf ( "var    = %.5f\n" ,  stats . var ());          StdOut . println ( stats );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AcyclicLP.java edu/princeton/cs/algs4/AcyclicLP.java /******************************************************************************  *  Compilation:  javac AcyclicLP.java  *  Execution:    java AcyclicP V E  *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java  *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt  *    *  Computes longeset paths in an edge-weighted acyclic digraph.  *  *  Remark: should probably check that graph is a DAG before running  *  *  % java AcyclicLP tinyEWDAG.txt 5  *  5 to 0 (2.44)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->0  0.38   

 *  5 to 1 (0.32)  5->1  0.32   

 *  5 to 2 (2.77)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   7->2  0.34   

 *  5 to 3 (0.61)  5->1  0.32   1->3  0.29   

 *  5 to 4 (2.06)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   

 *  5 to 5 (0.00)  

 *  5 to 6 (1.13)  5->1  0.32   1->3  0.29   3->6  0.52   

 *  5 to 7 (2.43)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 AcyclicLP} class represents a data type for solving the

 *  single-source longest paths problem in edge-weighted directed

 *  acyclic graphs (DAGs). The edge weights can be positive, negative, or zero.

 *  

 *  This implementation uses a topological-sort based algorithm.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted digraph).

 *  

 *  For additional documentation,   

 *  see Section 4.4 of   

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
AcyclicLP
 
{

    
private
 
double
[]
 distTo
;
          
// distTo[v] = distance  of longest s->v path

    
private
 
DirectedEdge
[]
 edgeTo
;
    
// edgeTo[v] = last edge on longest s->v path

    
/**

     * Computes a longest paths tree from {
@code
 s} to every other vertex in

     * the directed acyclic graph {
@code
 G}.

     * 
@param
 G the acyclic digraph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException if the digraph is not acyclic

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   AcyclicLP ( EdgeWeightedDigraph  G ,   int  s )   {         distTo  =   new   double [ G . V ()];         edgeTo  =   new   DirectedEdge [ G . V ()];         validateVertex ( s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =   Double . NEGATIVE_INFINITY ;         distTo [ s ]   =   0.0 ;          // relax vertices in topological order          Topological  topological  =   new   Topological ( G );          if   ( ! topological . hasOrder ())              throw   new   IllegalArgumentException ( "Digraph is not acyclic." );          for   ( int  v  :  topological . order ())   {              for   ( DirectedEdge  e  :  G . adj ( v ))                 relax ( e );          }      }      // relax edge e, but update if you find a *longer* path      private   void  relax ( DirectedEdge  e )   {          int  v  =  e . from (),  w  =  e . to ();          if   ( distTo [ w ]   <  distTo [ v ]   +  e . weight ())   {             distTo [ w ]   =  distTo [ v ]   +  e . weight ();             edgeTo [ w ]   =  e ;          }              }      /**      * Returns the length of a longest path from the source vertex { @code  s} to vertex { @code  v}.      *  @param   v the destination vertex      *  @return  the length of a longest path from the source vertex { @code  s} to vertex { @code  v};      *         { @code  Double.NEGATIVE_INFINITY} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   double  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Is there a path from the source vertex { @code  s} to vertex { @code  v}?      *  @param   v the destination vertex      *  @return  { @code  true} if there is a path from the source vertex      *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ]   >
 
Double
.
NEGATIVE_INFINITY
;

    
}

    
/**

     * Returns a longest path from the source vertex {
@code
 s} to vertex {
@code
 v}.

     * 
@param
  v the destination vertex

     * 
@return
 a longest path from the source vertex {
@code
 s} to vertex {
@code
 v}

     *         as an iterable of edges, and {
@code
 null} if no such path

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   Iterable < DirectedEdge >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< DirectedEdge >
 path 
=
 
new
 
Stack
< DirectedEdge >
();

        
for
 
(
DirectedEdge
 e 
=
 edgeTo
[
v
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
e
.
from
()])
 
{

            path
.
push
(
e
);

        
}

        
return
 path
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 AcyclicLP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
in
);

        
AcyclicLP
 lp 
=
 
new
 
AcyclicLP
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( lp . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  v ,  lp . distTo ( v ));                  for   ( DirectedEdge  e  :  lp . pathTo ( v ))   {                      StdOut . print ( e  +   "   " );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d         no path\n" ,  s ,  v );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AcyclicSP.java edu/princeton/cs/algs4/AcyclicSP.java /******************************************************************************  *  Compilation:  javac AcyclicSP.java  *  Execution:    java AcyclicSP V E  *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java  *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt  *  *  Computes shortest paths in an edge-weighted acyclic digraph.  *  *  % java AcyclicSP tinyEWDAG.txt 5  *  5 to 0 (0.73)  5->4  0.35   4->0  0.38   

 *  5 to 1 (0.32)  5->1  0.32   

 *  5 to 2 (0.62)  5->7  0.28   7->2  0.34   

 *  5 to 3 (0.61)  5->1  0.32   1->3  0.29   

 *  5 to 4 (0.35)  5->4  0.35   

 *  5 to 5 (0.00)  

 *  5 to 6 (1.13)  5->1  0.32   1->3  0.29   3->6  0.52   

 *  5 to 7 (0.28)  5->7  0.28   

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 AcyclicSP} class represents a data type for solving the

 *  single-source shortest paths problem in edge-weighted directed acyclic

 *  graphs (DAGs). The edge weights can be positive, negative, or zero.

 *  

 *  This implementation uses a topological-sort based algorithm.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted digraph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
AcyclicSP
 
{

    
private
 
double
[]
 distTo
;
         
// distTo[v] = distance  of shortest s->v path

    
private
 
DirectedEdge
[]
 edgeTo
;
   
// edgeTo[v] = last edge on shortest s->v path

    
/**

     * Computes a shortest paths tree from {
@code
 s} to every other vertex in

     * the directed acyclic graph {
@code
 G}.

     * 
@param
 G the acyclic digraph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException if the digraph is not acyclic

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   AcyclicSP ( EdgeWeightedDigraph  G ,   int  s )   {         distTo  =   new   double [ G . V ()];         edgeTo  =   new   DirectedEdge [ G . V ()];         validateVertex ( s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =   Double . POSITIVE_INFINITY ;         distTo [ s ]   =   0.0 ;          // visit vertices in topological order          Topological  topological  =   new   Topological ( G );          if   ( ! topological . hasOrder ())              throw   new   IllegalArgumentException ( "Digraph is not acyclic." );          for   ( int  v  :  topological . order ())   {              for   ( DirectedEdge  e  :  G . adj ( v ))                 relax ( e );          }      }      // relax edge e      private   void  relax ( DirectedEdge  e )   {          int  v  =  e . from (),  w  =  e . to ();          if   ( distTo [ w ]   >
 distTo
[
v
]
 
+
 e
.
weight
())
 
{

            distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 e
.
weight
();

            edgeTo
[
w
]
 
=
 e
;

        
}
       

    
}

    
/**

     * Returns the length of a shortest path from the source vertex {
@code
 s} to vertex {
@code
 v}.

     * 
@param
  v the destination vertex

     * 
@return
 the length of a shortest path from the source vertex {
@code
 s} to vertex {
@code
 v};

     *         {
@code
 Double.POSITIVE_INFINITY} if no such path

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   double  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Is there a path from the source vertex { @code  s} to vertex { @code  v}?      *  @param   v the destination vertex      *  @return  { @code  true} if there is a path from the source vertex      *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns a shortest path from the source vertex { @code  s} to vertex { @code  v}.      *  @param   v the destination vertex      *  @return  a shortest path from the source vertex { @code  s} to vertex { @code  v}      *         as an iterable of edges, and { @code  null} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < DirectedEdge >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< DirectedEdge >
 path 
=
 
new
 
Stack
< DirectedEdge >
();

        
for
 
(
DirectedEdge
 e 
=
 edgeTo
[
v
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
e
.
from
()])
 
{

            path
.
push
(
e
);

        
}

        
return
 path
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 AcyclicSP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
in
);

        
// find shortest path from s to each other vertex in DAG

        
AcyclicSP
 sp 
=
 
new
 
AcyclicSP
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( sp . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  v ,  sp . distTo ( v ));                  for   ( DirectedEdge  e  :  sp . pathTo ( v ))   {                      StdOut . print ( e  +   "   " );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d         no path\n" ,  s ,  v );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java /******************************************************************************  *  Compilation:  javac AdjMatrixEdgeWeightedDigraph.java  *  Execution:    java AdjMatrixEdgeWeightedDigraph V E  *  Dependencies: StdOut.java  *  *  An edge-weighted digraph, implemented using an adjacency matrix.  *  Parallel edges are disallowed; self-loops are allowed.  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  AdjMatrixEdgeWeightedDigraph} class represents a edge-weighted  *  digraph of vertices named 0 through V – 1, where each

 *  directed edge is of type {
@link
 DirectedEdge} and has a real-valued weight.

 *  It supports the following two primary operations: add a directed edge

 *  to the digraph and iterate over all of edges incident from a given vertex.

 *  It also provides

 *  methods for returning the number of vertices V and the number

 *  of edges E. Parallel edges are disallowed; self-loops are permitted.

 *  

 *  This implementation uses an adjacency-matrix representation.

 *  All operations take constant time (in the worst case) except

 *  iterating over the edges incident from a given vertex, which takes

 *  time proportional to V.

 *  

 *  For additional documentation,

 *  see Section 4.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
AdjMatrixEdgeWeightedDigraph
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;

    
private
 
int
 E
;

    
private
 
DirectedEdge
[][]
 adj
;

    

    
/**

     * Initializes an empty edge-weighted digraph with {
@code
 V} vertices and 0 edges.

     * 
@param
 V the number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   AdjMatrixEdgeWeightedDigraph ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "number of vertices must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;          this . adj  =   new   DirectedEdge [ V ][ V ];      }      /**      * Initializes a random edge-weighted digraph with { @code  V} vertices and E edges.

     * 
@param
 V the number of vertices

     * 
@param
 E the number of edges

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      *  @throws  IllegalArgumentException if { @code  E < 0}      */      public   AdjMatrixEdgeWeightedDigraph ( int  V ,   int  E )   {          this ( V );          if   ( E  <   0 )   throw   new   IllegalArgumentException ( "number of edges must be nonnegative" );          if   ( E  >
 V
*
V
)
 
throw
 
new
 
IllegalArgumentException
(
“too many edges”
);

        
// can be inefficient

        
while
 
(
this
.

!=
 E
)
 
{

            
int
 v 
=
 
StdRandom
.
uniform
(
V
);

            
int
 w 
=
 
StdRandom
.
uniform
(
V
);

            
double
 weight 
=
 
Math
.
round
(
100
 
*
 
StdRandom
.
uniform
())
 
/
 
100.0
;

            addEdge
(
new
 
DirectedEdge
(
v
,
 w
,
 weight
));

        
}

    
}

    
/**

     * Returns the number of vertices in the edge-weighted digraph.

     * 
@return
 the number of vertices in the edge-weighted digraph

     */

    
public
 
int
 V
()
 
{

        
return
 V
;

    
}

    
/**

     * Returns the number of edges in the edge-weighted digraph.

     * 
@return
 the number of edges in the edge-weighted digraph

     */

    
public
 
int
 E
()
 
{

        
return
 E
;

    
}

    
/**

     * Adds the directed edge {
@code
 e} to the edge-weighted digraph (if there

     * is not already an edge with the same endpoints).

     * 
@param
 e the edge

     */

    
public
 
void
 addEdge
(
DirectedEdge
 e
)
 
{

        
int
 v 
=
 e
.
from
();

        
int
 w 
=
 e
.
to
();

        validateVertex
(
v
);

        validateVertex
(
w
);

        
if
 
(
adj
[
v
][
w
]
 
==
 
null
)
 
{

            E
++
;

            adj
[
v
][
w
]
 
=
 e
;

        
}

    
}

    
/**

     * Returns the directed edges incident from vertex {
@code
 v}.

     * 
@param
 v the vertex

     * 
@return
 the directed edges incident from vertex {
@code
 v} as an Iterable

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   Iterable < DirectedEdge >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 
new
 
AdjIterator
(
v
);

    
}

    
// support iteration over graph vertices

    
private
 
class
 
AdjIterator
 
implements
 
Iterator
< DirectedEdge >
,
 
Iterable
< DirectedEdge >
 
{

        
private
 
int
 v
;

        
private
 
int
 w 
=
 
0
;

        
public
 
AdjIterator
(
int
 v
)
 
{

            
this
.

=
 v
;

        
}

        
public
 
Iterator
< DirectedEdge >
 iterator
()
 
{

            
return
 
this
;

        
}

        
public
 
boolean
 hasNext
()
 
{

            
while
 
(

<  V )   {                  if   ( adj [ v ][ w ]   !=   null )   return   true ;                 w ++ ;              }              return   false ;          }          public   DirectedEdge  next ()   {              if   ( ! hasNext ())   {                  throw   new   NoSuchElementException ();              }              return  adj [ v ][ w ++ ];          }          public   void  remove ()   {              throw   new   UnsupportedOperationException ();          }      }      /**      * Returns a string representation of the edge-weighted digraph. This method takes      * time proportional to V2.

     * 
@return
 the number of vertices V, followed by the number of edges E,

     *   followed by the V adjacency lists of edges

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” ”
 
+
 E 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( v  +   ": " );              for   ( DirectedEdge  e  :  adj ( v ))   {                 s . append ( e  +   "  " );              }             s . append ( NEWLINE );          }          return  s . toString ();      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 AdjMatrixEdgeWeightedDigraph} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
AdjMatrixEdgeWeightedDigraph
 G 
=
 
new
 
AdjMatrixEdgeWeightedDigraph
(
V
,
 E
);

        
StdOut
.
println
(
G
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Alphabet.java
edu/princeton/cs/algs4/Alphabet.java
/******************************************************************************

 *  Compilation:  javac Alphabet.java

 *  Execution:    java Alphabet

 *  Dependencies: StdOut.java

 *  

 *  A data type for alphabets, for use with string-processing code

 *  that must convert between an alphabet of size R and the integers

 *  0 through R-1.

 *

 *  Warning: supports only the basic multilingual plane (BMP), i.e,

 *           Unicode characters between U+0000 and U+FFFF.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

public
 
class
 
Alphabet
 
{

    
/**

     *  The binary alphabet { 0, 1 }.

     */

    
public
 
static
 
final
 
Alphabet
 BINARY 
=
 
new
 
Alphabet
(
“01”
);

    
/**

     *  The octal alphabet { 0, 1, 2, 3, 4, 5, 6, 7 }.

     */

    
public
 
static
 
final
 
Alphabet
 OCTAL 
=
 
new
 
Alphabet
(
“01234567”
);

    
/**

     *  The decimal alphabet { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }.

     */

    
public
 
static
 
final
 
Alphabet
 DECIMAL 
=
 
new
 
Alphabet
(
“0123456789”
);

    
/**

     *  The hexadecimal alphabet { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F }.

     */

    
public
 
static
 
final
 
Alphabet
 HEXADECIMAL 
=
 
new
 
Alphabet
(
“0123456789ABCDEF”
);

    
/**

     *  The DNA alphabet { A, C, T, G }.

     */

    
public
 
static
 
final
 
Alphabet
 DNA 
=
 
new
 
Alphabet
(
“ACGT”
);

    
/**

     *  The lowercase alphabet { a, b, c, …, z }.

     */

    
public
 
static
 
final
 
Alphabet
 LOWERCASE 
=
 
new
 
Alphabet
(
“abcdefghijklmnopqrstuvwxyz”
);

    
/**

     *  The uppercase alphabet { A, B, C, …, Z }.

     */

    
public
 
static
 
final
 
Alphabet
 UPPERCASE 
=
 
new
 
Alphabet
(
“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
);

    
/**

     *  The protein alphabet { A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y }.

     */

    
public
 
static
 
final
 
Alphabet
 PROTEIN 
=
 
new
 
Alphabet
(
“ACDEFGHIKLMNPQRSTVWY”
);

    
/**

     *  The base-64 alphabet (64 characters).

     */

    
public
 
static
 
final
 
Alphabet
 BASE64 
=
 
new
 
Alphabet
(
“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”
);

    
/**

     *  The ASCII alphabet (0-127).

     */

    
public
 
static
 
final
 
Alphabet
 ASCII 
=
 
new
 
Alphabet
(
128
);

    
/**

     *  The extended ASCII alphabet (0-255).

     */

    
public
 
static
 
final
 
Alphabet
 EXTENDED_ASCII 
=
 
new
 
Alphabet
(
256
);

    
/**

     *  The Unicode 16 alphabet (0-65,535).

     */

    
public
 
static
 
final
 
Alphabet
 UNICODE16      
=
 
new
 
Alphabet
(
65536
);

    
private
 
char
[]
 alphabet
;
     
// the characters in the alphabet

    
private
 
int
[]
 inverse
;
       
// indices

    
private
 
final
 
int
 R
;
         
// the radix of the alphabet

    
/**

     * Initializes a new alphabet from the given set of characters.

     *

     * 
@param
 alpha the set of characters

     */

    
public
 
Alphabet
(
String
 alpha
)
 
{

        
// check that alphabet contains no duplicate chars

        
boolean
[]
 unicode 
=
 
new
 
boolean
[
Character
.
MAX_VALUE
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  alpha . length ();  i ++ )   {              char  c  =  alpha . charAt ( i );              if   ( unicode [ c ])                  throw   new   IllegalArgumentException ( "Illegal alphabet: repeated character = '"   +  c  +   "'" );             unicode [ c ]   =   true ;          }         alphabet  =  alpha . toCharArray ();         R  =  alpha . length ();         inverse  =   new   int [ Character . MAX_VALUE ];          for   ( int  i  =   0 ;  i  <  inverse . length ;  i ++ )             inverse [ i ]   =   - 1 ;          // can't use char since R can be as big as 65,536          for   ( int  c  =   0 ;  c  <  R ;  c ++ )             inverse [ alphabet [ c ]]   =  c ;      }      /**      * Initializes a new alphabet using characters 0 through R-1.      *      *  @param  radix the number of characters in the alphabet (the radix R)      */      private   Alphabet ( int  radix )   {          this . R  =  radix ;         alphabet  =   new   char [ R ];         inverse  =   new   int [ R ];          // can't use char since R can be as big as 65,536          for   ( int  i  =   0 ;  i  <  R ;  i ++ )             alphabet [ i ]   =   ( char )  i ;          for   ( int  i  =   0 ;  i  <  R ;  i ++ )             inverse [ i ]   =  i ;      }      /**      * Initializes a new alphabet using characters 0 through 255.      */      public   Alphabet ()   {          this ( 256 );      }      /**      * Returns true if the argument is a character in this alphabet.      *      *  @param   c the character      *  @return  { @code  true} if { @code  c} is a character in this alphabet;      *         { @code  false} otherwise      */      public   boolean  contains ( char  c )   {          return  inverse [ c ]   !=   - 1 ;      }      /**      * Returns the number of characters in this alphabet (the radix).      *       *  @return  the number of characters in this alphabet      *  @deprecated  Replaced by { @link  #radix()}.      */     @ Deprecated      public   int  R ()   {          return  R ;      }      /**      * Returns the number of characters in this alphabet (the radix).      *       *  @return  the number of characters in this alphabet      */      public   int  radix ()   {          return  R ;      }      /**      * Returns the binary logarithm of the number of characters in this alphabet.      *       *  @return  the binary logarithm (rounded up) of the number of characters in this alphabet      */      public   int  lgR ()   {          int  lgR  =   0 ;          for   ( int  t  =  R - 1 ;  t  >=
 
1
;
 t 
/=
 
2
)

            lgR
++
;

        
return
 lgR
;

    
}

    
/**

     * Returns the index corresponding to the argument character.

     * 

     * 
@param
  c the character

     * 
@return
 the index corresponding to the character {
@code
 c}

     * 
@throws
 IllegalArgumentException unless {
@code
 c} is a character in this alphabet

     */

    
public
 
int
 toIndex
(
char
 c
)
 
{

        
if
 
(

>=
 inverse
.
length 
||
 inverse
[
c
]
 
==
 

1
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Character ”
 
+
 c 
+
 
” not in alphabet”
);

        
}

        
return
 inverse
[
c
];

    
}

    
/**

     * Returns the indices corresponding to the argument characters.

     * 

     * 
@param
  s the characters

     * 
@return
 the indices corresponding to the characters {
@code
 s}

     * 
@throws
 IllegalArgumentException unless every character in {
@code
 s}

     *         is a character in this alphabet

     */

    
public
 
int
[]
 toIndices
(
String
 s
)
 
{

        
char
[]
 source 
=
 s
.
toCharArray
();

        
int
[]
 target  
=
 
new
 
int
[
s
.
length
()];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  source . length ;  i ++ )             target [ i ]   =  toIndex ( source [ i ]);          return  target ;      }      /**      * Returns the character corresponding to the argument index.      *       *  @param   index the index      *  @return  the character corresponding to the index { @code  index}      *  @throws  IllegalArgumentException unless { @code  0 <= index < R}      */      public   char  toChar ( int  index )   {          if   ( index  <   0   ||  index  >=
 R
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index must be between 0 and ”
 
+
 R 
+
 
“: ”
 
+
 index
);

        
}

        
return
 alphabet
[
index
];

    
}

    
/**

     * Returns the characters corresponding to the argument indices.

     * 

     * 
@param
  indices the indices

     * 
@return
 the characters corresponding to the indices {
@code
 indices}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 < indices[i] < R}      *         for every { @code  i}      */      public   String  toChars ( int []  indices )   {          StringBuilder  s  =   new   StringBuilder ( indices . length );          for   ( int  i  =   0 ;  i  <  indices . length ;  i ++ )             s . append ( toChar ( indices [ i ]));          return  s . toString ();      }      /**      * Unit tests the { @code  Alphabet} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int []   encoded1  =   Alphabet . BASE64 . toIndices ( "NowIsTheTimeForAllGoodMen" );          String  decoded1  =   Alphabet . BASE64 . toChars ( encoded1 );          StdOut . println ( decoded1 );            int []   encoded2  =   Alphabet . DNA . toIndices ( "AACGAACGGTTTACCCCG" );          String  decoded2  =   Alphabet . DNA . toChars ( encoded2 );          StdOut . println ( decoded2 );          int []   encoded3  =   Alphabet . DECIMAL . toIndices ( "01234567890123456789" );          String  decoded3  =   Alphabet . DECIMAL . toChars ( encoded3 );          StdOut . println ( decoded3 );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AmericanFlag.java edu/princeton/cs/algs4/AmericanFlag.java /******************************************************************************  *  Compilation:  javac AmericanFlag.java  *  Execution:    java AmericanFlag < input.txt  *                java AmericanFlag int < input-non-negative-ints.txt    *  Dependencies: StdIn.java StdOut.java Stack.java  *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *                https://algs4.cs.princeton.edu/51radix/shells.txt  *  *  Sort an array of strings or integers in-place using American flag sort.  *  *  % java AmericanFlag < shells.txt   *  are  *  by  *  sea  *  seashells  *  seashells  *  sells  *  sells  *  she  *  she  *  shells  *  shore  *  surely  *  the  *  the  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  AmericanFlag} class provides static methods for sorting an  *  array of extended ASCII strings or integers in-place using   *  American flag sort. This is a non-recursive implementation.  *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne

 *  and 

 *  Engineering Radix Sort by McIlroy and Bostic.

 *  For a version that uses only one auxilary array, see {
@link
 AmericanFlagX}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 Ivan Pesin

 */

public
 
class
 
AmericanFlag
 
{

    
private
 
static
 
final
 
int
 BITS_PER_BYTE 
=
   
8
;

    
private
 
static
 
final
 
int
 BITS_PER_INT  
=
  
32
;
   
// each Java int is 32 bits 

    
private
 
static
 
final
 
int
 R             
=
 
256
;
   
// extend ASCII alphabet size

    
private
 
static
 
final
 
int
 CUTOFF        
=
  
15
;
   
// cutoff to insertion sort

    
// do not instantiate

    
private
 
AmericanFlag
()
 
{
 
}
 

    
// return dth character of s, -1 if d = length of string

    
private
 
static
 
int
 charAt
(
String
 s
,
 
int
 d
)
 
{

        
assert
 d 
>=
 
0
 
&&
 d 
<=  s . length ();          if   ( d  ==  s . length ())   return   - 1 ;          return  s . charAt ( d );      }      /**      * Rearranges the array of extended ASCII strings in ascending order.      * This is an unstable sorting algorithm.      *      *  @param  a the array to be sorted      */      public   static   void  sort ( String []  a )   {         sort ( a ,   0 ,  a . length  -   1 );      }      // sort from a[lo] to a[hi], starting at the dth character      public   static   void  sort ( String []  a ,   int  lo ,   int  hi )   {          // one-time allocation of data structures          Stack < Integer >
 st 
=
 
new
 
Stack
< Integer >
();

        
int
[]
 first 
=
 
new
 
int
[
R
+
2
];

        
int
[]
 next  
=
 
new
 
int
[
R
+
2
];

        
int
 d 
=
 
0
;
 
// character index to sort by

        st
.
push
(
lo
);

        st
.
push
(
hi
);

        st
.
push
(
d
);

        

        
while
 
(
!
st
.
isEmpty
())
 
{

            d 
=
 st
.
pop
();

            hi 
=
 st
.
pop
();

            lo 
=
 st
.
pop
();

        

            
if
 
(
hi 
<=  lo  +  CUTOFF )   {                 insertion ( a ,  lo ,  hi ,  d );                  continue ;              }              // compute frequency counts              for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {                  int  c  =  charAt ( a [ i ],  d )   +   1 ;   // account for -1 representing end-of-string                 first [ c + 1 ] ++ ;              }              // first[c] = location of first string whose dth character = c             first [ 0 ]   =  lo ;              for   ( int  c  =   0 ;  c  <=  R ;  c ++ )   {                 first [ c + 1 ]   +=  first [ c ];                               if   ( c  >
 
0
 
&&
 first
[
c
+
1
]

1
 
>
 first
[
c
])
 
{
 

                    
// add subproblem for character c (excludes sentinel c == 0)

                    st
.
push
(
first
[
c
]);

                    st
.
push
(
first
[
c
+
1
]
 

 
1
);

                    st
.
push
(
d
+
1
);
 

                
}

            
}

            
// next[c] = location to place next string whose dth character = c

            
for
 
(
int
 c 
=
 
0
;
 c 
<  R + 2 ;  c ++ )                 next [ c ]   =  first [ c ];              // permute data in place              for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {                  int  c  =  charAt ( a [ k ],  d )   +   1 ;                  while   ( first [ c ]   >
 k
)
 
{

                    exch
(
a
,
 k
,
 next
[
c
]
++
);

                    c 
=
 charAt
(
a
[
k
],
 d
)
 
+
 
1
;

                
}

                next
[
c
]
++
;

            
}

          

            
// clear first[] and next[] arrays

            
for
 
(
int
 c 
=
 
0
;
 c 
<  R + 2 ;  c ++ )   {                 first [ c ]   =   0 ;                 next [ c ]   =   0 ;              }          }      }           // insertion sort a[lo..hi], starting at dth character      private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
String
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
String
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    
// is v less than w, starting at character d

    
private
 
static
 
boolean
 less
(
String
 v
,
 
String
 w
,
 
int
 d
)
 
{

        
// assert v.substring(0, d).equals(w.substring(0, d));

        
for
 
(
int
 i 
=
 d
;
 i 
<    Math . min ( v . length (),  w . length ());  i ++ )   {              if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;              if   ( v . charAt ( i )   >
 w
.
charAt
(
i
))
 
return
 
false
;

        
}

        
return
 v
.
length
()
 
<  w . length ();      }     /**      * Rearranges the array of 32-bit integers in ascending order.      * Currently assumes that the integers are nonnegative.      *      *  @param  a the array to be sorted      */      public   static   void  sort ( int []  a )   {         sort ( a ,   0 ,  a . length - 1 );      }      // MSD sort from a[lo] to a[hi]      private   static   void  sort ( int []  a ,   int  lo ,   int  hi )   {          // one-time allocation of data structures          Stack < Integer >
 st 
=
 
new
 
Stack
< Integer >
();

        
int
[]
 first 
=
 
new
 
int
[
R
+
1
];

        
int
[]
 next  
=
 
new
 
int
[
R
+
1
];

        
int
 mask 
=
 R 

 
1
;
   
// 0xFF;

        
int
 d 
=
 
0
;
          
// byte to sort by

        st
.
push
(
lo
);

        st
.
push
(
hi
);

        st
.
push
(
d
);

        

        
while
 
(
!
st
.
isEmpty
())
 
{

            d 
=
 st
.
pop
();

            hi 
=
 st
.
pop
();

            lo 
=
 st
.
pop
();

        

            
if
 
(
hi 
<=  lo  +  CUTOFF )   {                 insertion ( a ,  lo ,  hi ,  d );                  continue ;              }                         // compute frequency counts (need R = 256)              int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * d  -  BITS_PER_BYTE ;              for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {                  int  c  =   ( a [ i ]   >>
 shift
)
 
&
 mask
;

                first
[
c
+
1
]
++
;

            
}

            
// first[c] = location of first int whose dth byte = c

            first
[
0
]
 
=
 lo
;

            
for
 
(
int
 c 
=
 
0
;
 c 
<  R ;  c ++ )   {                 first [ c + 1 ]   +=  first [ c ];                               if   ( d  <   3   &&  first [ c + 1 ] - 1   >
 first
[
c
])
 
{
 

                    
// add subproblem for byte c

                    st
.
push
(
first
[
c
]);

                    st
.
push
(
first
[
c
+
1
]
 

 
1
);

                    st
.
push
(
d
+
1
);
 

                
}

            
}

            
// next[c] = location to place next string whose dth byte = c

            
for
 
(
int
 c 
=
 
0
;
 c 
<  R + 1 ;  c ++ )                 next [ c ]   =  first [ c ];              // permute data in place              for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {                  int  c  =   ( a [ k ]   >>
 shift
)
 
&
 mask
;

                
while
 
(
first
[
c
]
 
>
 k
)
 
{

                    exch
(
a
,
 k
,
 next
[
c
]
++
);

                    c 
=
 
(
a
[
k
]
 
>>
 shift
)
 
&
 mask
;

                
}

                next
[
c
]
++
;

            
}

          

            
// clear first[] and next[] arrays

            
for
 
(
int
 c 
=
 
0
;
 c 
<  R + 1 ;  c ++ )   {                 first [ c ]   =   0 ;                 next [ c ]   =   0 ;              }          }      }      // insertion sort a[lo..hi], starting at dth byte      private   static   void  insertion ( int []  a ,   int  lo ,   int  hi ,   int  d )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
int
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
int
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    

    
// is v less than w, starting at byte d

    
private
 
static
 
boolean
 less
(
int
 v
,
 
int
 w
,
 
int
 d
)
 
{

        
int
 mask 
=
 R 

 
1
;
   
// 0xFF;

        
for
 
(
int
 i 
=
 d
;
 i 
<   4 ;  i ++ )   {              int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * i  -  BITS_PER_BYTE ;              int  a  =   ( v  >>
 shift
)
 
&
 mask
;

            
int
 b 
=
 
(

>>
 shift
)
 
&
 mask
;

            
if
 
(

<  b )   return   true ;              if   ( a  >
 b
)
 
return
 
false
;

        
}

        
return
 
false
;

    
}

    

    
/**

     * Reads in a sequence of extended ASCII strings or non-negative ints from standard input;

     * American flag sorts them;

     * and prints them to standard output in ascending order.

     *

     * 
@param
 args the command-line arguments: “int” to read input as non-negative integers

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
if
 
(
args
.
length 
>
 
0
 
&&
 args
[
0
].
equals
(
“int”
))
 
{

            
int
[]
 a 
=
 
StdIn
.
readAllInts
();

            sort
(
a
);

            
// print results

            
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )                  StdOut . println ( a [ i ]);          }          else   {              String []  a  =   StdIn . readAllStrings ();             sort ( a );              // print results              for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )                  StdOut . println ( a [ i ]);          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AmericanFlagX.java edu/princeton/cs/algs4/AmericanFlagX.java /******************************************************************************  *  Compilation:  javac AmericanFlagX.java  *  Execution:    java AmericanFlagX < input.txt  *  Dependencies: StdIn.java StdOut.java Stack.java  *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *                https://algs4.cs.princeton.edu/51radix/shells.txt  *  *  Sort an array of strings or integers in-place using American Flag sort.  *  *  % java AmericanFlagX < shells.txt   *  are  *  by  *  sea  *  seashells  *  seashells  *  sells  *  sells  *  she  *  she  *  shells  *  shore  *  surely  *  the  *  the  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  AmericanFlagX} class provides static methods for sorting an  *  array of extended ASCII strings or integers in-place using   *  American Flag sort. This implementation is non-recursive and uses only   *  one auxiliary array.  *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne

 *  and 

 *  Engineering Radix Sort by McIlroy and Bostic.

 *  For a version that uses two auxilary arrays, see {
@link
 AmericanFlag}.

 *

 *  
@author
 Ivan Pesin

 */

public
 
class
 
AmericanFlagX
 
{

    
private
 
static
 
final
 
int
 R      
=
 
256
;
   
// extend ASCII alphabet size

    
private
 
static
 
final
 
int
 CUTOFF 
=
  
15
;
   
// cutoff to insertion sort

    
// do not instantiate

    
private
 
AmericanFlagX
()
 
{
 
}
 

    
// return dth character of s, -1 if d = length of string

    
private
 
static
 
int
 charAt
(
String
 s
,
 
int
 d
)
 
{

        
assert
 d 
>=
 
0
 
&&
 d 
<=  s . length ();          if   ( d  ==  s . length ())   return   - 1 ;          return  s . charAt ( d );      }      /**      * Rearranges the array of extended ASCII strings in ascending order.      * This is an unstable in-place sorting algorithm.      *      *  @param  a the array to be sorted      */      public   static   void  sort ( String []  a )   {         sort ( a ,   0 ,  a . length  -   1 );      }      // sort from a[lo] to a[hi], starting at the dth character      public   static   void  sort ( String []  a ,   int  lo ,   int  hi )   {          // one-time allocation of data structures          Stack < Integer >
 st 
=
 
new
 
Stack
< Integer >
();

        
int
[]
 count 
=
 
new
 
int
[
R
+
1
];

        
int
 d 
=
 
0
;
 
// character index to sort by

        st
.
push
(
lo
);

        st
.
push
(
hi
);

        st
.
push
(
d
);

        

        
while
 
(
!
st
.
isEmpty
())
 
{

            d 
=
 st
.
pop
();

            hi 
=
 st
.
pop
();

            lo 
=
 st
.
pop
();

            
if
 
(
hi 
<=  lo  +  CUTOFF )   {                 insertion ( a ,  lo ,  hi ,  d );                  continue ;              }              // compute frequency counts              for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {                  int  c  =  charAt ( a [ i ],  d )   +   1 ;   // account for -1 representing end-of-string                 count [ c ] ++ ;              }              // accumulate counts relative to a[0], so that               // count[c] is the number of keys <= c             count [ 0 ]   +=  lo ;              for   ( int  c  =   0 ;  c  <  R ;  c ++ )   {                 count [ c + 1 ]   +=  count [ c ];                               if   ( c  >
 
0
 
&&
 count
[
c
+
1
]

1
 
>
 count
[
c
])
 
{
 

                    
// add subproblem for character c (excludes sentinel c == 0)

                    st
.
push
(
count
[
c
]);

                    st
.
push
(
count
[
c
+
1
]

1
);

                    st
.
push
(
d
+
1
);
 

                
}

            
}

            
// permute data in place

            
// for details and proof see Knuth Theorem 5.1.2B and ch 5.2 excercise 13.

            
for
 
(
int
 r 
=
 hi
;
 r 
>=
 lo
;
 r

)
 
{

                
// locate element that must be shifted right of r

                
int
 c 
=
 charAt
(
a
[
r
],
 d
)
 
+
 
1
;

                
while
 
(

>=
 lo 
&&
 count
[
c
]

1
 
<=  r )   {                      if   ( count [ c ] - 1   ==  r )  count [ c ] -- ;                     r -- ;                      if   ( r  >=
 lo
)
 c 
=
 charAt
(
a
[
r
],
 d
)
 
+
 
1
;

                
}

                
// if r < lo the subarray is sorted.                  if   ( r  <  lo )   break ;                               // permute a[r] until correct element is in place                  while   ( -- count [ c ]   !=  r )   {                     exch ( a ,  r ,  count [ c ]);                     c  =  charAt ( a [ r ],  d )   +   1 ;                  }              }                         // clear count[] array              for   ( int  c  =   0 ;  c  <  R + 1 ;  c ++ )                 count [ c ]   =   0 ;          }      }           // insertion sort a[lo..hi], starting at dth character      private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
String
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
String
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    
// is v less than w, starting at character d

    
private
 
static
 
boolean
 less
(
String
 v
,
 
String
 w
,
 
int
 d
)
 
{

        
// assert v.substring(0, d).equals(w.substring(0, d));

        
for
 
(
int
 i 
=
 d
;
 i 
<    Math . min ( v . length (),  w . length ());  i ++ )   {              if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;              if   ( v . charAt ( i )   >
 w
.
charAt
(
i
))
 
return
 
false
;

        
}

        
return
 v
.
length
()
 
<  w . length ();      }               /**      * Reads in a sequence of extended ASCII strings or non-negative ints from standard input;      * American flag sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {                 String []  a  =   StdIn . readAllStrings ();         sort ( a );          // print results          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Arbitrage.java edu/princeton/cs/algs4/Arbitrage.java /******************************************************************************  *  Compilation:  javac Arbitrage.java  *  Execution:    java Arbitrage < input.txt  *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java  *                BellmanFordSP.java  *  Data file:    https://algs4.cs.princeton.edu/44sp/rates.txt  *  *  Arbitrage detection.  *  *  % more rates.txt  *  5  *  USD 1      0.741  0.657  1.061  1.005  *  EUR 1.349  1      0.888  1.433  1.366  *  GBP 1.521  1.126  1      1.614  1.538  *  CHF 0.942  0.698  0.619  1      0.953  *  CAD 0.995  0.732  0.650  1.049  1  *  *  % java Arbitrage < rates.txt  *  1000.00000 USD =  741.00000 EUR  *   741.00000 EUR = 1012.20600 CAD  *  1012.20600 CAD = 1007.14497 USD  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Arbitrage} class provides a client that finds an arbitrage  *  opportunity in a currency exchange table by constructing a  *  complete-digraph representation of the exchange table and then finding  *  a negative cycle in the digraph.  *  

 *  This implementation uses the Bellman-Ford algorithm to find a

 *  negative cycle in the complete digraph.

 *  The running time is proportional to V3 in the

 *  worst case, where V is the number of currencies.

 *  

 *  For additional documentation,

 *  see Section 4.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Arbitrage
 
{

    
// this class cannot be instantiated

    
private
 
Arbitrage
()
 
{
 
}

    
/**

     *  Reads the currency exchange table from standard input and

     *  prints an arbitrage opportunity to standard output (if one exists).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// V currencies

        
int
 V 
=
 
StdIn
.
readInt
();

        
String
[]
 name 
=
 
new
 
String
[
V
];

        
// create complete network

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
V
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             name [ v ]   =   StdIn . readString ();              for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {                  double  rate  =   StdIn . readDouble ();                  DirectedEdge  e  =   new   DirectedEdge ( v ,  w ,   - Math . log ( rate ));                 G . addEdge ( e );              }          }          // find negative cycle          BellmanFordSP  spt  =   new   BellmanFordSP ( G ,   0 );          if   ( spt . hasNegativeCycle ())   {              double  stake  =   1000.0 ;              for   ( DirectedEdge  e  :  spt . negativeCycle ())   {                  StdOut . printf ( "%10.5f %s " ,  stake ,  name [ e . from ()]);                 stake  *=   Math . exp ( - e . weight ());                  StdOut . printf ( "= %10.5f %s\n" ,  stake ,  name [ e . to ()]);              }          }          else   {              StdOut . println ( "No arbitrage opportunity" );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/AssignmentProblem.java edu/princeton/cs/algs4/AssignmentProblem.java /******************************************************************************  *  Compilation:  javac AssignmentProblem.java  *  Execution:    java AssignmentProblem n  *  Dependencies: DijkstraSP.java DirectedEdge.java  *  *  Solve an n-by-n assignment problem in n^3 log n time using the  *  successive shortest path algorithm.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  AssignmentProblem} class represents a data type for computing  *  an optimal solution to an n-by-n assignment problem.

 *  The assignment problem is to find a minimum weight matching in an

 *  edge-weighted complete bipartite graph.

 *  

 *  The data type supplies methods for determining the optimal solution

 *  and the corresponding dual solution.

 *  

 *  This implementation uses the successive shortest paths algorithm.

 *  The order of growth of the running time in the worst case is

 *  O(n^3 log n) to solve an n-by-n

 *  instance.

 *  

 *  For additional documentation, see

 *  Section 6.5

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
AssignmentProblem
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-14
;

    
private
 
static
 
final
 
int
 UNMATCHED 
=
 

1
;

    
private
 
int
 n
;
              
// number of rows and columns

    
private
 
double
[][]
 weight
;
  
// the n-by-n cost matrix

    
private
 
double
 minWeight
;
   
// minimum value of any weight

    
private
 
double
[]
 px
;
        
// px[i] = dual variable for row i

    
private
 
double
[]
 py
;
        
// py[j] = dual variable for col j

    
private
 
int
[]
 xy
;
           
// xy[i] = j means i-j is a match

    
private
 
int
[]
 yx
;
           
// yx[j] = i means i-j is a match

    
/**

     * Determines an optimal solution to the assignment problem.

     *

     * 
@param
  weight the n-by-n matrix of weights

     * 
@throws
 IllegalArgumentException unless all weights are nonnegative

     * 
@throws
 IllegalArgumentException if {
@code
 weight} is {
@code
 null}

     */
 

    
public
 
AssignmentProblem
(
double
[][]
 weight
)
 
{

        
if
 
(
weight 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“constructor argument is null”
);

        n 
=
 weight
.
length
;

        
this
.
weight 
=
 
new
 
double
[
n
][
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( Double . isNaN ( weight [ i ][ j ]))                      throw   new   IllegalArgumentException ( "weight "   +  i  +   "-"   +  j   +   " is NaN" );                  if   ( weight [ i ][ j ]   <  minWeight )  minWeight  =  weight [ i ][ j ];                  this . weight [ i ][ j ]   =  weight [ i ][ j ];              }          }          // dual variables         px  =   new   double [ n ];         py  =   new   double [ n ];          // initial matching is empty         xy  =   new   int [ n ];         yx  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              xy [ i ]   =  UNMATCHED ;          for   ( int  j  =   0 ;  j  <  n ;  j ++ )              yx [ j ]   =  UNMATCHED ;          // add n edges to matching          for   ( int  k  =   0 ;  k  <  n ;  k ++ )   {              assert  isDualFeasible ();              assert  isComplementarySlack ();             augment ();          }          assert  certifySolution ();      }      // find shortest augmenting path and upate      private   void  augment ()   {          // build residual graph          EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( 2 * n + 2 );          int  s  =   2 * n ,  t  =   2 * n + 1 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( xy [ i ]   ==  UNMATCHED )                 G . addEdge ( new   DirectedEdge ( s ,  i ,   0.0 ));          }          for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {              if   ( yx [ j ]   ==  UNMATCHED )                 G . addEdge ( new   DirectedEdge ( n + j ,  t ,  py [ j ]));          }          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( xy [ i ]   ==  j )  G . addEdge ( new   DirectedEdge ( n + j ,  i ,   0.0 ));                  else             G . addEdge ( new   DirectedEdge ( i ,  n + j ,  reducedCost ( i ,  j )));              }          }          // compute shortest path from s to every other vertex          DijkstraSP  spt  =   new   DijkstraSP ( G ,  s );          // augment along alternating path          for   ( DirectedEdge  e  :  spt . pathTo ( t ))   {              int  i  =  e . from (),  j  =  e . to ()   -  n ;              if   ( i  <  n )   {                 xy [ i ]   =  j ;                 yx [ j ]   =  i ;              }          }          // update dual variables          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             px [ i ]   +=  spt . distTo ( i );          for   ( int  j  =   0 ;  j  <  n ;  j ++ )             py [ j ]   +=  spt . distTo ( n + j );      }      // reduced cost of i-j      // (subtracting off minWeight reweights all weights to be non-negative)      private   double  reducedCost ( int  i ,   int  j )   {          double  reducedCost  =   ( weight [ i ][ j ]   -  minWeight )   +  px [ i ]   -  py [ j ];          // to avoid issues with floating-point precision          double  magnitude  =   Math . abs ( weight [ i ][ j ])   +   Math . abs ( px [ i ])   +   Math . abs ( py [ j ]);          if   ( Math . abs ( reducedCost )   <=  FLOATING_POINT_EPSILON  *  magnitude )   return   0.0 ;          assert  reducedCost  >=
 
0.0
;

        
return
 reducedCost
;

    
}

    
/**

     * Returns the dual optimal value for the specified row.

     *

     * 
@param
  i the row index

     * 
@return
 the dual optimal value for row {
@code
 i}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= i < n}      *      */      // dual variable for row i      public   double  dualRow ( int  i )   {         validate ( i );          return  px [ i ];      }      /**      * Returns the dual optimal value for the specified column.      *      *  @param   j the column index      *  @return  the dual optimal value for column { @code  j}      *  @throws  IllegalArgumentException unless { @code  0 <= j < n}      *      */      public   double  dualCol ( int  j )   {         validate ( j );          return  py [ j ];      }      /**      * Returns the column associated with the specified row in the optimal solution.      *      *  @param   i the row index      *  @return  the column matched to row { @code  i} in the optimal solution      *  @throws  IllegalArgumentException unless { @code  0 <= i < n}      *      */      public   int  sol ( int  i )   {         validate ( i );          return  xy [ i ];      }      /**      * Returns the total weight of the optimal solution      *      *  @return  the total weight of the optimal solution      *      */      public   double  weight ()   {          double  total  =   0.0 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( xy [ i ]   !=  UNMATCHED )                 total  +=  weight [ i ][ xy [ i ]];          }          return  total ;      }      private   void  validate ( int  i )   {          if   ( i  <   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
(
“index is not between 0 and ”
 
+
 
(
n

1
)
 
+
 
“: ”
 
+
 i
);

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// check that dual variables are feasible

    
private
 
boolean
 isDualFeasible
()
 
{

        
// check that all edges have >= 0 reduced cost

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( reducedCost ( i ,  j )   <   0 )   {                      StdOut . println ( "Dual variables are not feasible" );                      return   false ;                  }              }          }          return   true ;      }      // check that primal and dual variables are complementary slack      private   boolean  isComplementarySlack ()   {          // check that all matched edges have 0-reduced cost          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   (( xy [ i ]   !=  UNMATCHED )   &&   ( reducedCost ( i ,  xy [ i ])   !=   0 ))   {                  StdOut . println ( "Primal and dual variables are not complementary slack" );                  return   false ;              }          }          return   true ;      }      // check that primal variables are a perfect matching      private   boolean  isPerfectMatching ()   {          // check that xy[] is a perfect matching          boolean []  perm  =   new   boolean [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( perm [ xy [ i ]])   {                  StdOut . println ( "Not a perfect matching" );                  return   false ;              }             perm [ xy [ i ]]   =   true ;          }          // check that xy[] and yx[] are inverses          for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {              if   ( xy [ yx [ j ]]   !=  j )   {                  StdOut . println ( "xy[] and yx[] are not inverses" );                  return   false ;              }          }          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( yx [ xy [ i ]]   !=  i )   {                  StdOut . println ( "xy[] and yx[] are not inverses" );                  return   false ;              }          }          return   true ;      }      // check optimality conditions      private   boolean  certifySolution ()   {          return  isPerfectMatching ()   &&  isDualFeasible ()   &&  isComplementarySlack ();      }      /**      * Unit tests the { @code  AssignmentProblem} data type.      * Takes a command-line argument n; creates a random n-by-n matrix;      * solves the n-by-n assignment problem; and prints the optimal      * solution.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // create random n-by-n matrix          int  n  =   Integer . parseInt ( args [ 0 ]);          double [][]  weight  =   new   double [ n ][ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 weight [ i ][ j ]   =   StdRandom . uniform ( 900 )   +   100 ;    // 3 digits              }          }          // solve assignment problem          AssignmentProblem  assignment  =   new   AssignmentProblem ( weight );          StdOut . printf ( "weight = %.0f\n" ,  assignment . weight ());          StdOut . println ();          // print n-by-n matrix and optimal solution          if   ( n  >=
 
20
)
 
return
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( j  ==  assignment . sol ( i ))                      StdOut . printf ( "*%.0f " ,  weight [ i ][ j ]);                  else                      StdOut . printf ( " %.0f " ,  weight [ i ][ j ]);              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Average.java edu/princeton/cs/algs4/Average.java /******************************************************************************  *  Compilation:  javac Average.java  *  Execution:    java Average < data.txt  *  Dependencies: StdIn.java StdOut.java  *    *  Reads in a sequence of real numbers, and computes their average.  *  *  % java Average  *  10.0 5.0 6.0  *  3.0 7.0 32.0  *  [Ctrl-d]  *  Average is 10.5  *  *  Note [Ctrl-d] signifies the end of file on Unix.  *  On windows use [Ctrl-z].  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Average} class provides a client for reading in a sequence  *  of real numbers and printing out their average.  *  

 *  For additional documentation, see Section 1.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Average
 
{
 

    
// this class should not be instantiated

    
private
 
Average
()
 
{
 
}

    
/**

     * Reads in a sequence of real numbers from standard input and prints

     * out their average to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{
 

        
int
 count 
=
 
0
;
       
// number input values

        
double
 sum 
=
 
0.0
;
    
// sum of input values

        
// read data and compute statistics

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
double
 value 
=
 
StdIn
.
readDouble
();

            sum 
+=
 value
;

            count
++
;

        
}

        
// compute the average

        
double
 average 
=
 sum 
/
 count
;

        
// print results

        
StdOut
.
println
(
“Average is ”
 
+
 average
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/AVLTreeST.java
edu/princeton/cs/algs4/AVLTreeST.java
/******************************************************************************

 *  Compilation:  javac AVLTreeST.java

 *  Execution:    java AVLTreeST < input.txt  *  Dependencies: StdIn.java StdOut.java    *  Data files:   https://algs4.cs.princeton.edu/33balanced/tinyST.txt    *      *  A symbol table implemented using an AVL tree.  *  *  % more tinyST.txt  *  S E A R C H E X A M P L E  *    *  % java AVLTreeST < tinyST.txt  *  A 8  *  C 4  *  E 12  *  H 5  *  L 11  *  M 9  *  P 10  *  R 3  *  S 0  *  X 7  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  AVLTreeST} class represents an ordered symbol table of  *  generic key-value pairs. It supports the usual putget,

 *  containsdeletesize, and is-empty

 *  methods. It also provides ordered methods for finding the minimum,

 *  maximumfloor, and ceiling. It also provides a

 *  keys method for iterating over all of the keys. A symbol table

 *  implements the associative array abstraction: when associating a

 *  value with a key that is already in the symbol table, the convention is to

 *  replace the old value with the new value. Unlike {
@link
 java.util.Map}, this

 *  class uses the convention that values cannot be {
@code
 null}

 *  —setting the value associated with a key to {
@code
 null} is

 *  equivalent to deleting the key from the symbol table.

 *  

 *  This symbol table implementation uses internally an

 *   AVL tree  (Georgy

 *  Adelson-Velsky and Evgenii Landis’ tree) which is a self-balancing BST.

 *  In an AVL tree, the heights of the two child subtrees of any

 *  node differ by at most one; if at any time they differ by more than one,

 *  rebalancing is done to restore this property.

 *  

 *  This implementation requires that the key type implements the

 *  {
@code
 Comparable} interface and calls the {
@code
 compareTo()} and

 *  method to compare two keys. It does not call either {
@code
 equals()} or

 *  {
@code
 hashCode()}. The putgetcontains,

 *  deleteminimummaximumceiling, and

 *  floor operations each take logarithmic time in the worst case. The

 *  size, and is-empty operations take constant time.

 *  Construction also takes constant time.

 * 

 *  For other implementations of the same API, see {
@link
 ST}, {
@link
 BinarySearchST},

 *  {
@link
 SequentialSearchST}, {
@link
 BST}, {
@link
 RedBlackBST},

 *  {
@link
 SeparateChainingHashST}, and {
@link
 LinearProbingHashST}.

 * 

 *  
@author
 Marcelo Silva

 */

public
 
class
 
AVLTreeST
< Key   extends   Comparable < Key >
,
 
Value
>
 
{

    
/**

     * The root node.

     */

    
private
 
Node
 root
;

    
/**

     * This class represents an inner node of the AVL tree.

     */

    
private
 
class
 
Node
 
{

        
private
 
final
 
Key
 key
;
   
// the key

        
private
 
Value
 val
;
       
// the associated value

        
private
 
int
 height
;
      
// height of the subtree

        
private
 
int
 size
;
        
// number of nodes in subtree

        
private
 
Node
 left
;
       
// left subtree

        
private
 
Node
 right
;
      
// right subtree

        
public
 
Node
(
Key
 key
,
 
Value
 val
,
 
int
 height
,
 
int
 size
)
 
{

            
this
.
key 
=
 key
;

            
this
.
val 
=
 val
;

            
this
.
size 
=
 size
;

            
this
.
height 
=
 height
;

        
}

    
}

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
AVLTreeST
()
 
{

    
}

    
/**

     * Checks if the symbol table is empty.

     * 

     * 
@return
 {
@code
 true} if the symbol table is empty.

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 root 
==
 
null
;

    
}

    
/**

     * Returns the number key-value pairs in the symbol table.

     * 

     * 
@return
 the number key-value pairs in the symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 size
(
root
);

    
}

    
/**

     * Returns the number of nodes in the subtree.

     * 

     * 
@param
 x the subtree

     * 

     * 
@return
 the number of nodes in the subtree

     */

    
private
 
int
 size
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
0
;

        
return
 x
.
size
;

    
}

    
/**

     * Returns the height of the internal AVL tree. It is assumed that the

     * height of an empty tree is -1 and the height of a tree with just one node

     * is 0.

     * 

     * 
@return
 the height of the internal AVL tree

     */

    
public
 
int
 height
()
 
{

        
return
 height
(
root
);

    
}

    
/**

     * Returns the height of the subtree.

     * 

     * 
@param
 x the subtree

     * 

     * 
@return
 the height of the subtree.

     */

    
private
 
int
 height
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 

1
;

        
return
 x
.
height
;

    
}

    
/**

     * Returns the value associated with the given key.

     * 

     * 
@param
 key the key

     * 
@return
 the value associated with the given key if the key is in the

     *         symbol table and {
@code
 null} if the key is not in the

     *         symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);

        
Node
 x 
=
 get
(
root
,
 key
);

        
if
 
(

==
 
null
)
 
return
 
null
;

        
return
 x
.
val
;

    
}

    
/**

     * Returns value associated with the given key in the subtree or

     * {
@code
 null} if no such key.

     * 

     * 
@param
 x the subtree

     * 
@param
 key the key

     * 
@return
 value associated with the given key in the subtree or

     *         {
@code
 null} if no such key

     */

    
private
 
Node
 get
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
 
(
cmp 
<   0 )   return  get ( x . left ,  key );          else   if   ( cmp  >
 
0
)
 
return
 get
(
x
.
right
,
 key
);

        
else
 
return
 x
;

    
}

    
/**

     * Checks if the symbol table contains the given key.

     * 

     * 
@param
 key the key

     * 
@return
 {
@code
 true} if the symbol table contains {
@code
 key}

     *         and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting

     * the old value with the new value if the symbol table already contains the

     * specified key. Deletes the specified key (and its associated value) from

     * this symbol table if the specified value is {
@code
 null}.

     * 

     * 
@param
 key the key

     * 
@param
 val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to put() is null”
);

        
if
 
(
val 
==
 
null
)
 
{

            delete
(
key
);

            
return
;

        
}

        root 
=
 put
(
root
,
 key
,
 val
);

        
assert
 check
();

    
}

    
/**

     * Inserts the key-value pair in the subtree. It overrides the old value

     * with the new value if the symbol table already contains the specified key

     * and deletes the specified key (and its associated value) from this symbol

     * table if the specified value is {
@code
 null}.

     * 

     * 
@param
 x the subtree

     * 
@param
 key the key

     * 
@param
 val the value

     * 
@return
 the subtree

     */

    
private
 
Node
 put
(
Node
 x
,
 
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(

==
 
null
)
 
return
 
new
 
Node
(
key
,
 val
,
 
0
,
 
1
);

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
 
(
cmp 
<   0 )   {             x . left  =  put ( x . left ,  key ,  val );          }          else   if   ( cmp  >
 
0
)
 
{

            x
.
right 
=
 put
(
x
.
right
,
 key
,
 val
);

        
}

        
else
 
{

            x
.
val 
=
 val
;

            
return
 x
;

        
}

        x
.
size 
=
 
1
 
+
 size
(
x
.
left
)
 
+
 size
(
x
.
right
);

        x
.
height 
=
 
1
 
+
 
Math
.
max
(
height
(
x
.
left
),
 height
(
x
.
right
));

        
return
 balance
(
x
);

    
}

    
/**

     * Restores the AVL tree property of the subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 the subtree with restored AVL property

     */

    
private
 
Node
 balance
(
Node
 x
)
 
{

        
if
 
(
balanceFactor
(
x
)
 
<   - 1 )   {              if   ( balanceFactor ( x . right )   >
 
0
)
 
{

                x
.
right 
=
 rotateRight
(
x
.
right
);

            
}

            x 
=
 rotateLeft
(
x
);

        
}

        
else
 
if
 
(
balanceFactor
(
x
)
 
>
 
1
)
 
{

            
if
 
(
balanceFactor
(
x
.
left
)
 
<   0 )   {                 x . left  =  rotateLeft ( x . left );              }             x  =  rotateRight ( x );          }          return  x ;      }      /**      * Returns the balance factor of the subtree. The balance factor is defined      * as the difference in height of the left subtree and right subtree, in      * this order. Therefore, a subtree with a balance factor of -1, 0 or 1 has      * the AVL property since the heights of the two child subtrees differ by at      * most one.      *       *  @param  x the subtree      *  @return  the balance factor of the subtree      */      private   int  balanceFactor ( Node  x )   {          return  height ( x . left )   -  height ( x . right );      }      /**      * Rotates the given subtree to the right.      *       *  @param  x the subtree      *  @return  the right rotated subtree      */      private   Node  rotateRight ( Node  x )   {          Node  y  =  x . left ;         x . left  =  y . right ;         y . right  =  x ;         y . size  =  x . size ;         x . size  =   1   +  size ( x . left )   +  size ( x . right );         x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));         y . height  =   1   +   Math . max ( height ( y . left ),  height ( y . right ));          return  y ;      }      /**      * Rotates the given subtree to the left.      *       *  @param  x the subtree      *  @return  the left rotated subtree      */      private   Node  rotateLeft ( Node  x )   {          Node  y  =  x . right ;         x . right  =  y . left ;         y . left  =  x ;         y . size  =  x . size ;         x . size  =   1   +  size ( x . left )   +  size ( x . right );         x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));         y . height  =   1   +   Math . max ( height ( y . left ),  height ( y . right ));          return  y ;      }      /**      * Removes the specified key and its associated value from the symbol table      * (if the key is in the symbol table).      *       *  @param  key the key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  delete ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );          if   ( ! contains ( key ))   return ;         root  =  delete ( root ,  key );          assert  check ();      }      /**      * Removes the specified key and its associated value from the given      * subtree.      *       *  @param  x the subtree      *  @param  key the key      *  @return  the updated subtree      */      private   Node  delete ( Node  x ,   Key  key )   {          int  cmp  =  key . compareTo ( x . key );          if   ( cmp  <   0 )   {             x . left  =  delete ( x . left ,  key );          }          else   if   ( cmp  >
 
0
)
 
{

            x
.
right 
=
 delete
(
x
.
right
,
 key
);

        
}

        
else
 
{

            
if
 
(
x
.
left 
==
 
null
)
 
{

                
return
 x
.
right
;

            
}

            
else
 
if
 
(
x
.
right 
==
 
null
)
 
{

                
return
 x
.
left
;

            
}

            
else
 
{

                
Node
 y 
=
 x
;

                x 
=
 min
(
y
.
right
);

                x
.
right 
=
 deleteMin
(
y
.
right
);

                x
.
left 
=
 y
.
left
;

            
}

        
}

        x
.
size 
=
 
1
 
+
 size
(
x
.
left
)
 
+
 size
(
x
.
right
);

        x
.
height 
=
 
1
 
+
 
Math
.
max
(
height
(
x
.
left
),
 height
(
x
.
right
));

        
return
 balance
(
x
);

    
}

    
/**

     * Removes the smallest key and associated value from the symbol table.

     * 

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called deleteMin() with empty symbol table”
);

        root 
=
 deleteMin
(
root
);

        
assert
 check
();

    
}

    
/**

     * Removes the smallest key and associated value from the given subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 the updated subtree

     */

    
private
 
Node
 deleteMin
(
Node
 x
)
 
{

        
if
 
(
x
.
left 
==
 
null
)
 
return
 x
.
right
;

        x
.
left 
=
 deleteMin
(
x
.
left
);

        x
.
size 
=
 
1
 
+
 size
(
x
.
left
)
 
+
 size
(
x
.
right
);

        x
.
height 
=
 
1
 
+
 
Math
.
max
(
height
(
x
.
left
),
 height
(
x
.
right
));

        
return
 balance
(
x
);

    
}

    
/**

     * Removes the largest key and associated value from the symbol table.

     * 

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMax
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called deleteMax() with empty symbol table”
);

        root 
=
 deleteMax
(
root
);

        
assert
 check
();

    
}

    
/**

     * Removes the largest key and associated value from the given subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 the updated subtree

     */

    
private
 
Node
 deleteMax
(
Node
 x
)
 
{

        
if
 
(
x
.
right 
==
 
null
)
 
return
 x
.
left
;

        x
.
right 
=
 deleteMax
(
x
.
right
);

        x
.
size 
=
 
1
 
+
 size
(
x
.
left
)
 
+
 size
(
x
.
right
);

        x
.
height 
=
 
1
 
+
 
Math
.
max
(
height
(
x
.
left
),
 height
(
x
.
right
));

        
return
 balance
(
x
);

    
}

    
/**

     * Returns the smallest key in the symbol table.

     * 

     * 
@return
 the smallest key in the symbol table

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called min() with empty symbol table”
);

        
return
 min
(
root
).
key
;

    
}

    
/**

     * Returns the node with the smallest key in the subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 the node with the smallest key in the subtree

     */

    
private
 
Node
 min
(
Node
 x
)
 
{

        
if
 
(
x
.
left 
==
 
null
)
 
return
 x
;

        
return
 min
(
x
.
left
);

    
}

    
/**

     * Returns the largest key in the symbol table.

     * 

     * 
@return
 the largest key in the symbol table

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called max() with empty symbol table”
);

        
return
 max
(
root
).
key
;

    
}

    
/**

     * Returns the node with the largest key in the subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 the node with the largest key in the subtree

     */

    
private
 
Node
 max
(
Node
 x
)
 
{

        
if
 
(
x
.
right 
==
 
null
)
 
return
 x
;

        
return
 max
(
x
.
right
);

    
}

    
/**

     * Returns the largest key in the symbol table less than or equal to

     * {
@code
 key}.

     * 

     * 
@param
 key the key

     * 
@return
 the largest key in the symbol table less than or equal to

     *         {
@code
 key}

     * 
@throws
 NoSuchElementException if the symbol table is empty

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 floor
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to floor() is null”
);

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called floor() with empty symbol table”
);

        
Node
 x 
=
 floor
(
root
,
 key
);

        
if
 
(

==
 
null
)
 
return
 
null
;

        
else
 
return
 x
.
key
;

    
}

    
/**

     * Returns the node in the subtree with the largest key less than or equal

     * to the given key.

     * 

     * 
@param
 x the subtree

     * 
@param
 key the key

     * 
@return
 the node in the subtree with the largest key less than or equal

     *         to the given key

     */

    
private
 
Node
 floor
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
 
(
cmp 
==
 
0
)
 
return
 x
;

        
if
 
(
cmp 
<   0 )   return  floor ( x . left ,  key );          Node  y  =  floor ( x . right ,  key );          if   ( y  !=   null )   return  y ;          else   return  x ;      }      /**      * Returns the smallest key in the symbol table greater than or equal to      * { @code  key}.      *       *  @param  key the key      *  @return  the smallest key in the symbol table greater than or equal to      *         { @code  key}      *  @throws  NoSuchElementException if the symbol table is empty      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Key  ceiling ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );          if   ( isEmpty ())   throw   new   NoSuchElementException ( "called ceiling() with empty symbol table" );          Node  x  =  ceiling ( root ,  key );          if   ( x  ==   null )   return   null ;          else   return  x . key ;      }      /**      * Returns the node in the subtree with the smallest key greater than or      * equal to the given key.      *       *  @param  x the subtree      *  @param  key the key      *  @return  the node in the subtree with the smallest key greater than or      *         equal to the given key      */      private   Node  ceiling ( Node  x ,   Key  key )   {          if   ( x  ==   null )   return   null ;          int  cmp  =  key . compareTo ( x . key );          if   ( cmp  ==   0 )   return  x ;          if   ( cmp  >
 
0
)
 
return
 ceiling
(
x
.
right
,
 key
);

        
Node
 y 
=
 ceiling
(
x
.
left
,
 key
);

        
if
 
(

!=
 
null
)
 
return
 y
;

        
else
 
return
 x
;

    
}

    
/**

     * Returns the kth smallest key in the symbol table.

     * 

     * 
@param
 k the order statistic

     * 
@return
 the kth smallest key in the symbol table

     * 
@throws
 IllegalArgumentException unless {
@code
 k} is between 0 and

     *             {
@code
 size() -1 }

     */

    
public
 
Key
 select
(
int
 k
)
 
{

        
if
 
(

<   0   ||  k  >=
 size
())
 
throw
 
new
 
IllegalArgumentException
(
“k is not in range 0-”
 
+
 
(
size
()
 

 
1
));

        
Node
 x 
=
 select
(
root
,
 k
);

        
return
 x
.
key
;

    
}

    
/**

     * Returns the node with key the kth smallest key in the subtree.

     * 

     * 
@param
 x the subtree

     * 
@param
 k the kth smallest key in the subtree

     * 
@return
 the node with key the kth smallest key in the subtree

     */

    
private
 
Node
 select
(
Node
 x
,
 
int
 k
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 t 
=
 size
(
x
.
left
);

        
if
 
(

>
 k
)
 
return
 select
(
x
.
left
,
 k
);

        
else
 
if
 
(

<  k )   return  select ( x . right ,  k  -  t  -   1 );          else   return  x ;      }      /**      * Returns the number of keys in the symbol table strictly less than      * { @code  key}.      *       *  @param  key the key      *  @return  the number of keys in the symbol table strictly less than      *         { @code  key}      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   int  rank ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );          return  rank ( key ,  root );      }      /**      * Returns the number of keys in the subtree less than key.      *       *  @param  key the key      *  @param  x the subtree      *  @return  the number of keys in the subtree less than key      */      private   int  rank ( Key  key ,   Node  x )   {          if   ( x  ==   null )   return   0 ;          int  cmp  =  key . compareTo ( x . key );          if   ( cmp  <   0 )   return  rank ( key ,  x . left );          else   if   ( cmp  >
 
0
)
 
return
 
1
 
+
 size
(
x
.
left
)
 
+
 rank
(
key
,
 x
.
right
);

        
else
 
return
 size
(
x
.
left
);

    
}

    
/**

     * Returns all keys in the symbol table.

     * 

     * 
@return
 all keys in the symbol table

     */

    
public
 
Iterable
< Key >
 keys
()
 
{

        
return
 keysInOrder
();

    
}

    
/**

     * Returns all keys in the symbol table following an in-order traversal.

     * 

     * 
@return
 all keys in the symbol table following an in-order traversal

     */

    
public
 
Iterable
< Key >
 keysInOrder
()
 
{

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        keysInOrder
(
root
,
 queue
);

        
return
 queue
;

    
}

    
/**

     * Adds the keys in the subtree to queue following an in-order traversal.

     * 

     * 
@param
 x the subtree

     * 
@param
 queue the queue

     */

    
private
 
void
 keysInOrder
(
Node
 x
,
 
Queue
< Key >
 queue
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        keysInOrder
(
x
.
left
,
 queue
);

        queue
.
enqueue
(
x
.
key
);

        keysInOrder
(
x
.
right
,
 queue
);

    
}

    
/**

     * Returns all keys in the symbol table following a level-order traversal.

     * 

     * 
@return
 all keys in the symbol table following a level-order traversal.

     */

    
public
 
Iterable
< Key >
 keysLevelOrder
()
 
{

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        
if
 
(
!
isEmpty
())
 
{

            
Queue
< Node >
 queue2 
=
 
new
 
Queue
< Node >
();

            queue2
.
enqueue
(
root
);

            
while
 
(
!
queue2
.
isEmpty
())
 
{

                
Node
 x 
=
 queue2
.
dequeue
();

                queue
.
enqueue
(
x
.
key
);

                
if
 
(
x
.
left 
!=
 
null
)
 
{

                    queue2
.
enqueue
(
x
.
left
);

                
}

                
if
 
(
x
.
right 
!=
 
null
)
 
{

                    queue2
.
enqueue
(
x
.
right
);

                
}

            
}

        
}

        
return
 queue
;

    
}

    
/**

     * Returns all keys in the symbol table in the given range.

     * 

     * 
@param
 lo the lowest key

     * 
@param
 hi the highest key

     * 
@return
 all keys in the symbol table between {
@code
 lo} (inclusive)

     *         and {
@code
 hi} (exclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *             is {
@code
 null}

     */

    
public
 
Iterable
< Key >
 keys
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to keys() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to keys() is null”
);

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        keys
(
root
,
 queue
,
 lo
,
 hi
);

        
return
 queue
;

    
}

    
/**

     * Adds the keys between {
@code
 lo} and {
@code
 hi} in the subtree

     * to the {
@code
 queue}.

     * 

     * 
@param
 x the subtree

     * 
@param
 queue the queue

     * 
@param
 lo the lowest key

     * 
@param
 hi the highest key

     */

    
private
 
void
 keys
(
Node
 x
,
 
Queue
< Key >
 queue
,
 
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
int
 cmplo 
=
 lo
.
compareTo
(
x
.
key
);

        
int
 cmphi 
=
 hi
.
compareTo
(
x
.
key
);

        
if
 
(
cmplo 
<   0 )  keys ( x . left ,  queue ,  lo ,  hi );          if   ( cmplo  <=   0   &&  cmphi  >=
 
0
)
 queue
.
enqueue
(
x
.
key
);

        
if
 
(
cmphi 
>
 
0
)
 keys
(
x
.
right
,
 queue
,
 lo
,
 hi
);

    
}

    
/**

     * Returns the number of keys in the symbol table in the given range.

     * 

     * 
@param
 lo minimum endpoint

     * 
@param
 hi maximum endpoint

     * 
@return
 the number of keys in the symbol table between {
@code
 lo}

     *         (inclusive) and {
@code
 hi} (exclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *             is {
@code
 null}

     */

    
public
 
int
 size
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to size() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to size() is null”
);

        
if
 
(
lo
.
compareTo
(
hi
)
 
>
 
0
)
 
return
 
0
;

        
if
 
(
contains
(
hi
))
 
return
 rank
(
hi
)
 

 rank
(
lo
)
 
+
 
1
;

        
else
 
return
 rank
(
hi
)
 

 rank
(
lo
);

    
}

    
/**

     * Checks if the AVL tree invariants are fine.

     * 

     * 
@return
 {
@code
 true} if the AVL tree invariants are fine

     */

    
private
 
boolean
 check
()
 
{

        
if
 
(
!
isBST
())
 
StdOut
.
println
(
“Symmetric order not consistent”
);

        
if
 
(
!
isAVL
())
 
StdOut
.
println
(
“AVL property not consistent”
);

        
if
 
(
!
isSizeConsistent
())
 
StdOut
.
println
(
“Subtree counts not consistent”
);

        
if
 
(
!
isRankConsistent
())
 
StdOut
.
println
(
“Ranks not consistent”
);

        
return
 isBST
()
 
&&
 isAVL
()
 
&&
 isSizeConsistent
()
 
&&
 isRankConsistent
();

    
}

    
/**

     * Checks if AVL property is consistent.

     * 

     * 
@return
 {
@code
 true} if AVL property is consistent.

     */

    
private
 
boolean
 isAVL
()
 
{

        
return
 isAVL
(
root
);

    
}

    
/**

     * Checks if AVL property is consistent in the subtree.

     * 

     * 
@param
 x the subtree

     * 
@return
 {
@code
 true} if AVL property is consistent in the subtree

     */

    
private
 
boolean
 isAVL
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
true
;

        
int
 bf 
=
 balanceFactor
(
x
);

        
if
 
(
bf 
>
 
1
 
||
 bf 
<   - 1 )   return   false ;          return  isAVL ( x . left )   &&  isAVL ( x . right );      }      /**      * Checks if the symmetric order is consistent.      *       *  @return  { @code  true} if the symmetric order is consistent      */      private   boolean  isBST ()   {          return  isBST ( root ,   null ,   null );      }      /**      * Checks if the tree rooted at x is a BST with all keys strictly between      * min and max (if min or max is null, treat as empty constraint) Credit:      * Bob Dondero's elegant solution      *       *  @param  x the subtree      *  @param  min the minimum key in subtree      *  @param  max the maximum key in subtree      *  @return  { @code  true} if if the symmetric order is consistent      */      private   boolean  isBST ( Node  x ,   Key  min ,   Key  max )   {          if   ( x  ==   null )   return   true ;          if   ( min  !=   null   &&  x . key . compareTo ( min )   <=   0 )   return   false ;          if   ( max  !=   null   &&  x . key . compareTo ( max )   >=
 
0
)
 
return
 
false
;

        
return
 isBST
(
x
.
left
,
 min
,
 x
.
key
)
 
&&
 isBST
(
x
.
right
,
 x
.
key
,
 max
);

    
}

    
/**

     * Checks if size is consistent.

     * 

     * 
@return
 {
@code
 true} if size is consistent

     */

    
private
 
boolean
 isSizeConsistent
()
 
{

        
return
 isSizeConsistent
(
root
);

    
}

    
/**

     * Checks if the size of the subtree is consistent.

     * 

     * 
@return
 {
@code
 true} if the size of the subtree is consistent

     */

    
private
 
boolean
 isSizeConsistent
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
true
;

        
if
 
(
x
.
size 
!=
 size
(
x
.
left
)
 
+
 size
(
x
.
right
)
 
+
 
1
)
 
return
 
false
;

        
return
 isSizeConsistent
(
x
.
left
)
 
&&
 isSizeConsistent
(
x
.
right
);

    
}

    
/**

     * Checks if rank is consistent.

     * 

     * 
@return
 {
@code
 true} if rank is consistent

     */

    
private
 
boolean
 isRankConsistent
()
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  size ();  i ++ )              if   ( i  !=  rank ( select ( i )))   return   false ;          for   ( Key  key  :  keys ())              if   ( key . compareTo ( select ( rank ( key )))   !=   0 )   return   false ;          return   true ;      }      /**      * Unit tests the { @code  AVLTreeST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          AVLTreeST < String ,   Integer >
 st 
=
 
new
 
AVLTreeST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
for
 
(
String
 s 
:
 st
.
keys
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

        
StdOut
.
println
();

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Bag.java
edu/princeton/cs/algs4/Bag.java
/******************************************************************************

 *  Compilation:  javac Bag.java

 *  Execution:    java Bag < input.txt  *  Dependencies: StdIn.java StdOut.java  *  *  A generic bag or multiset, implemented using a singly linked list.  *  *  % more tobe.txt   *  to be or not to - be - - that - - - is  *  *  % java Bag < tobe.txt  *  size of bag = 14  *  is  *  -  *  -  *  -  *  that  *  -  *  -  *  be  *  -  *  to  *  not  *  or  *  be  *  to  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  Bag} class represents a bag (or multiset) of   *  generic items. It supports insertion and iterating over the   *  items in arbitrary order.  *  

 *  This implementation uses a singly linked list with a static nested class Node.

 *  See {
@link
 LinkedBag} for the version from the

 *  textbook that uses a non-static nested class.

 *  See {
@link
 ResizingArrayBag} for a version that uses a resizing array.

 *  The addisEmpty, and size operations

 *  take constant time. Iteration takes time proportional to the number of items.

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of an item in this bag

 */

public
 
class
 
Bag
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Node
< Item >
 first
;
    
// beginning of bag

    
private
 
int
 n
;
               
// number of elements in bag

    
// helper linked list class

    
private
 
static
 
class
 
Node
< Item >
 
{

        
private
 
Item
 item
;

        
private
 
Node
< Item >
 next
;

    
}

    
/**

     * Initializes an empty bag.

     */

    
public
 
Bag
()
 
{

        first 
=
 
null
;

        n 
=
 
0
;

    
}

    
/**

     * Returns true if this bag is empty.

     *

     * 
@return
 {
@code
 true} if this bag is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in this bag.

     *

     * 
@return
 the number of items in this bag

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Adds the item to this bag.

     *

     * 
@param
  item the item to add to this bag

     */

    
public
 
void
 add
(
Item
 item
)
 
{

        
Node
< Item >
 oldfirst 
=
 first
;

        first 
=
 
new
 
Node
< Item >
();

        first
.
item 
=
 item
;

        first
.
next 
=
 oldfirst
;

        n
++
;

    
}

    
/**

     * Returns an iterator that iterates over the items in this bag in arbitrary order.

     *

     * 
@return
 an iterator that iterates over the items in this bag in arbitrary order

     */

    
public
 
Iterator
< Item >
 iterator
()
  
{

        
return
 
new
 
ListIterator
(
first
);
  

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
< Item >
 current
;

        
public
 
ListIterator
(
Node
< Item >
 first
)
 
{

            current 
=
 first
;

        
}

        
public
 
boolean
 hasNext
()
  
{
 
return
 current 
!=
 
null
;
                     
}

        
public
 
void
 remove
()
      
{
 
throw
 
new
 
UnsupportedOperationException
();
  
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 Bag} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Bag
< String >
 bag 
=
 
new
 
Bag
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            bag
.
add
(
item
);

        
}

        
StdOut
.
println
(
“size of bag = ”
 
+
 bag
.
size
());

        
for
 
(
String
 s 
:
 bag
)
 
{

            
StdOut
.
println
(
s
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BellmanFordSP.java
edu/princeton/cs/algs4/BellmanFordSP.java
/******************************************************************************

 *  Compilation:  javac BellmanFordSP.java

 *  Execution:    java BellmanFordSP filename.txt s

 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Queue.java

 *                EdgeWeightedDirectedCycle.java

 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDn.txt

 *                https://algs4.cs.princeton.edu/44sp/mediumEWDnc.txt

 *

 *  Bellman-Ford shortest path algorithm. Computes the shortest path tree in

 *  edge-weighted digraph G from vertex s, or finds a negative cost cycle

 *  reachable from s.

 *

 *  % java BellmanFordSP tinyEWDn.txt 0

 *  0 to 0 ( 0.00)  

 *  0 to 1 ( 0.93)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   4->5  0.35   5->1  0.32

 *  0 to 2 ( 0.26)  0->2  0.26   

 *  0 to 3 ( 0.99)  0->2  0.26   2->7  0.34   7->3  0.39   

 *  0 to 4 ( 0.26)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   

 *  0 to 5 ( 0.61)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   4->5  0.35

 *  0 to 6 ( 1.51)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   

 *  0 to 7 ( 0.60)  0->2  0.26   2->7  0.34   

 *

 *  % java BellmanFordSP tinyEWDnc.txt 0

 *  4->5  0.35

 *  5->4 -0.66

 *

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 BellmanFordSP} class represents a data type for solving the

 *  single-source shortest paths problem in edge-weighted digraphs with

 *  no negative cycles. 

 *  The edge weights can be positive, negative, or zero.

 *  This class finds either a shortest path from the source vertex s

 *  to every other vertex or a negative cycle reachable from the source vertex.

 *  

 *  This implementation uses a queue-based implementation of 

 *  the Bellman-Ford-Moore algorithm.

 *  The constructor takes Θ(V (V + E)) time

 *  in the worst case, where V is the number of vertices and

 *  E is the number of edges. In practice, it performs much better.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted digraph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BellmanFordSP
 
{

    
private
 
double
[]
 distTo
;
               
// distTo[v] = distance  of shortest s->v path

    
private
 
DirectedEdge
[]
 edgeTo
;
         
// edgeTo[v] = last edge on shortest s->v path

    
private
 
boolean
[]
 onQueue
;
             
// onQueue[v] = is v currently on the queue?

    
private
 
Queue
< Integer >
 queue
;
          
// queue of vertices to relax

    
private
 
int
 cost
;
                      
// number of calls to relax()

    
private
 
Iterable
< DirectedEdge >
 cycle
;
  
// negative cycle (or null if no such cycle)

    
/**

     * Computes a shortest paths tree from {
@code
 s} to every other vertex in

     * the edge-weighted digraph {
@code
 G}.

     * 
@param
 G the acyclic digraph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   BellmanFordSP ( EdgeWeightedDigraph  G ,   int  s )   {         distTo   =   new   double [ G . V ()];         edgeTo   =   new   DirectedEdge [ G . V ()];         onQueue  =   new   boolean [ G . V ()];          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =   Double . POSITIVE_INFINITY ;         distTo [ s ]   =   0.0 ;          // Bellman-Ford algorithm         queue  =   new   Queue < Integer >
();

        queue
.
enqueue
(
s
);

        onQueue
[
s
]
 
=
 
true
;

        
while
 
(
!
queue
.
isEmpty
()
 
&&
 
!
hasNegativeCycle
())
 
{

            
int
 v 
=
 queue
.
dequeue
();

            onQueue
[
v
]
 
=
 
false
;

            relax
(
G
,
 v
);

        
}

        
assert
 check
(
G
,
 s
);

    
}

    
// relax vertex v and put other endpoints on queue if changed

    
private
 
void
 relax
(
EdgeWeightedDigraph
 G
,
 
int
 v
)
 
{

        
for
 
(
DirectedEdge
 e 
:
 G
.
adj
(
v
))
 
{

            
int
 w 
=
 e
.
to
();

            
if
 
(
distTo
[
w
]
 
>
 distTo
[
v
]
 
+
 e
.
weight
())
 
{

                distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 e
.
weight
();

                edgeTo
[
w
]
 
=
 e
;

                
if
 
(
!
onQueue
[
w
])
 
{

                    queue
.
enqueue
(
w
);

                    onQueue
[
w
]
 
=
 
true
;

                
}

            
}

            
if
 
(
++
cost 
%
 G
.
V
()
 
==
 
0
)
 
{

                findNegativeCycle
();

                
if
 
(
hasNegativeCycle
())
 
return
;
  
// found a negative cycle

            
}

        
}

    
}

    
/**

     * Is there a negative cycle reachable from the source vertex {
@code
 s}?

     * 
@return
 {
@code
 true} if there is a negative cycle reachable from the

     *    source vertex {
@code
 s}, and {
@code
 false} otherwise

     */

    
public
 
boolean
 hasNegativeCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
/**

     * Returns a negative cycle reachable from the source vertex {
@code
 s}, or {
@code
 null}

     * if there is no such cycle.

     * 
@return
 a negative cycle reachable from the soruce vertex {
@code
 s} 

     *    as an iterable of edges, and {
@code
 null} if there is no such cycle

     */

    
public
 
Iterable
< DirectedEdge >
 negativeCycle
()
 
{

        
return
 cycle
;

    
}

    
// by finding a cycle in predecessor graph

    
private
 
void
 findNegativeCycle
()
 
{

        
int
 V 
=
 edgeTo
.
length
;

        
EdgeWeightedDigraph
 spt 
=
 
new
 
EdgeWeightedDigraph
(
V
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )              if   ( edgeTo [ v ]   !=   null )                 spt . addEdge ( edgeTo [ v ]);          EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( spt );         cycle  =  finder . cycle ();      }      /**      * Returns the length of a shortest path from the source vertex { @code  s} to vertex { @code  v}.      *  @param   v the destination vertex      *  @return  the length of a shortest path from the source vertex { @code  s} to vertex { @code  v};      *         { @code  Double.POSITIVE_INFINITY} if no such path      *  @throws  UnsupportedOperationException if there is a negative cost cycle reachable      *         from the source vertex { @code  s}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   double  distTo ( int  v )   {         validateVertex ( v );          if   ( hasNegativeCycle ())              throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );          return  distTo [ v ];      }      /**      * Is there a path from the source { @code  s} to vertex { @code  v}?      *  @param   v the destination vertex      *  @return  { @code  true} if there is a path from the source vertex      *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns a shortest path from the source { @code  s} to vertex { @code  v}.      *  @param   v the destination vertex      *  @return  a shortest path from the source { @code  s} to vertex { @code  v}      *         as an iterable of edges, and { @code  null} if no such path      *  @throws  UnsupportedOperationException if there is a negative cost cycle reachable      *         from the source vertex { @code  s}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < DirectedEdge >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
hasNegativeCycle
())

            
throw
 
new
 
UnsupportedOperationException
(
“Negative cost cycle exists”
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< DirectedEdge >
 path 
=
 
new
 
Stack
< DirectedEdge >
();

        
for
 
(
DirectedEdge
 e 
=
 edgeTo
[
v
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
e
.
from
()])
 
{

            path
.
push
(
e
);

        
}

        
return
 path
;

    
}

    
// check optimality conditions: either 

    
// (i) there exists a negative cycle reacheable from s

    
//     or 

    
// (ii)  for all edges e = v->w:            distTo[w] <= distTo[v] + e.weight()      // (ii') for all edges e = v->w on the SPT: distTo[w] == distTo[v] + e.weight()

    
private
 
boolean
 check
(
EdgeWeightedDigraph
 G
,
 
int
 s
)
 
{

        
// has a negative cycle

        
if
 
(
hasNegativeCycle
())
 
{

            
double
 weight 
=
 
0.0
;

            
for
 
(
DirectedEdge
 e 
:
 negativeCycle
())
 
{

                weight 
+=
 e
.
weight
();

            
}

            
if
 
(
weight 
>=
 
0.0
)
 
{

                
System
.
err
.
println
(
“error: weight of negative cycle = ”
 
+
 weight
);

                
return
 
false
;

            
}

        
}

        
// no negative cycle reachable from source

        
else
 
{

            
// check that distTo[v] and edgeTo[v] are consistent

            
if
 
(
distTo
[
s
]
 
!=
 
0.0
 
||
 edgeTo
[
s
]
 
!=
 
null
)
 
{

                
System
.
err
.
println
(
“distanceTo[s] and edgeTo[s] inconsistent”
);

                
return
 
false
;

            
}

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {                  if   ( v  ==  s )   continue ;                  if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {                      System . err . println ( "distTo[] and edgeTo[] inconsistent" );                      return   false ;                  }              }              // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  for   ( DirectedEdge  e  :  G . adj ( v ))   {                      int  w  =  e . to ();                      if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {                          System . err . println ( "edge "   +  e  +   " not relaxed" );                          return   false ;                      }                  }              }              // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()

            
for
 
(
int
 w 
=
 
0
;
 w 
<  G . V ();  w ++ )   {                  if   ( edgeTo [ w ]   ==   null )   continue ;                  DirectedEdge  e  =  edgeTo [ w ];                  int  v  =  e . from ();                  if   ( w  !=  e . to ())   return   false ;                  if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {                      System . err . println ( "edge "   +  e  +   " on shortest path not tight" );                      return   false ;                  }              }          }          StdOut . println ( "Satisfies optimality conditions" );          StdOut . println ();          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 BellmanFordSP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
in
);

        
BellmanFordSP
 sp 
=
 
new
 
BellmanFordSP
(
G
,
 s
);

        
// print negative cycle

        
if
 
(
sp
.
hasNegativeCycle
())
 
{

            
for
 
(
DirectedEdge
 e 
:
 sp
.
negativeCycle
())

                
StdOut
.
println
(
e
);

        
}

        
// print shortest paths

        
else
 
{

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {                  if   ( sp . hasPathTo ( v ))   {                      StdOut . printf ( "%d to %d (%5.2f)  " ,  s ,  v ,  sp . distTo ( v ));                      for   ( DirectedEdge  e  :  sp . pathTo ( v ))   {                          StdOut . print ( e  +   "   " );                      }                      StdOut . println ();                  }                  else   {                      StdOut . printf ( "%d to %d           no path\n" ,  s ,  v );                  }              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinaryDump.java edu/princeton/cs/algs4/BinaryDump.java /******************************************************************************  *  Compilation:  javac BinaryDump.java  *  Execution:    java BinaryDump n < file  *  Dependencies: BinaryStdIn.java  *  Data file:    https://introcs.cs.princeton.edu/stdlib/abra.txt  *    *  Reads in a binary file and writes out the bits, n per line.  *  *  % more abra.txt   *  ABRACADABRA!  *  *  % java BinaryDump 16 < abra.txt  *  0100000101000010  *  0101001001000001  *  0100001101000001  *  0100010001000001  *  0100001001010010  *  0100000100100001  *  96 bits  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BinaryDump} class provides a client for displaying the contents  *  of a binary file in binary.  *  

 *  For more full-featured versions, see the Unix utilities

 *  {
@code
 od} (octal dump) and {
@code
 hexdump} (hexadecimal dump).

 *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  See also {
@link
 HexDump} and {
@link
 PictureDump}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BinaryDump
 
{

    
// Do not instantiate.

    
private
 
BinaryDump
()
 
{
 
}

    
/**

     * Reads in a sequence of bytes from standard input and writes

     * them to standard output in binary, k bits per line,

     * where k is given as a command-line integer (defaults

     * to 16 if no integer is specified); also writes the number

     * of bits.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 bitsPerLine 
=
 
16
;

        
if
 
(
args
.
length 
==
 
1
)
 
{

            bitsPerLine 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
}

        
int
 count
;

        
for
 
(
count 
=
 
0
;
 
!
BinaryStdIn
.
isEmpty
();
 count
++
)
 
{

            
if
 
(
bitsPerLine 
==
 
0
)
 
{

                
BinaryStdIn
.
readBoolean
();

                
continue
;

            
}

            
else
 
if
 
(
count 
!=
 
0
 
&&
 count 
%
 bitsPerLine 
==
 
0
)
 
StdOut
.
println
();

            
if
 
(
BinaryStdIn
.
readBoolean
())
 
StdOut
.
print
(
1
);

            
else
                           
StdOut
.
print
(
0
);

        
}

        
if
 
(
bitsPerLine 
!=
 
0
)
 
StdOut
.
println
();

        
StdOut
.
println
(
count 
+
 
” bits”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BinaryIn.java
edu/princeton/cs/algs4/BinaryIn.java
/******************************************************************************

 *  Compilation:  javac BinaryIn.java

 *  Execution:    java BinaryIn input output

 *  Dependencies: none             

 *  

 *  This library is for reading binary data from an input stream.

 *

 *  % java BinaryIn https://introcs.cs.princeton.edu/java/cover  output

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
io
.
BufferedInputStream
;

import
 java
.
io
.
File
;

import
 java
.
io
.
FileInputStream
;

import
 java
.
io
.
IOException
;

import
 java
.
io
.
InputStream
;

import
 java
.
net
.
Socket
;

import
 java
.
net
.
URL
;

import
 java
.
net
.
URLConnection
;

import
 java
.
util
.
NoSuchElementException
;

/**

 *  Binary input. This class provides methods for reading

 *  in bits from a binary input stream, either

 *  one bit at a time (as a {
@code
 boolean}),

 *  8 bits at a time (as a {
@code
 byte} or {
@code
 char}),

 *  16 bits at a time (as a {
@code
 short}),

 *  32 bits at a time (as an {
@code
 int} or {
@code
 float}), or

 *  64 bits at a time (as a {
@code
 double} or {
@code
 long}).

 *  

 *  The binary input stream can be from standard input, a filename,

 *  a URL name, a Socket, or an InputStream.

 *  

 *  All primitive types are assumed to be represented using their 

 *  standard Java representations, in big-endian (most significant

 *  byte first) order.

 *  

 *  The client should not intermix calls to {
@code
 BinaryIn} with calls

 *  to {
@code
 In}; otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryIn
 
{

    
private
 
static
 
final
 
int
 EOF 
=
 

1
;
   
// end of file

    
private
 
BufferedInputStream
 in
;
      
// the input stream

    
private
 
int
 buffer
;
                  
// one character buffer

    
private
 
int
 n
;
                       
// number of bits left in buffer

   
/**

     * Initializes a binary input stream from standard input.

     */

    
public
 
BinaryIn
()
 
{

        in 
=
 
new
 
BufferedInputStream
(
System
.
in
);

        fillBuffer
();

    
}

   
/**

     * Initializes a binary input stream from an {
@code
 InputStream}.

     *

     * 
@param
 is the {
@code
 InputStream} object

     */

    
public
 
BinaryIn
(
InputStream
 is
)
 
{

        in 
=
 
new
 
BufferedInputStream
(
is
);

        fillBuffer
();

    
}

   
/**

     * Initializes a binary input stream from a socket.

     *

     * 
@param
 socket the socket

     */

    
public
 
BinaryIn
(
Socket
 socket
)
 
{

        
try
 
{

            
InputStream
 is 
=
 socket
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 socket
);

        
}

    
}

   
/**

     * Initializes a binary input stream from a URL.

     *

     * 
@param
 url the URL

     */

    
public
 
BinaryIn
(
URL url
)
 
{

        
try
 
{

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 url
);

        
}

    
}

   
/**

     * Initializes a binary input stream from a filename or URL name.

     *

     * 
@param
 name the name of the file or URL

     */

    
public
 
BinaryIn
(
String
 name
)
 
{

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
name
);

            
if
 
(
file
.
exists
())
 
{

                
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

                in 
=
 
new
 
BufferedInputStream
(
fis
);

                fillBuffer
();

                
return
;

            
}

            
// next try for files included in jar

            URL url 
=
 getClass
().
getResource
(
name
);

            
// or URL from web

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 
new
 URL
(
name
);

            
}

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 name
);

        
}

    
}

    
private
 
void
 fillBuffer
()
 
{

        
try
 
{

            buffer 
=
 in
.
read
();

            n 
=
 
8
;

        
}

        
catch
 
(
IOException
 e
)
 
{

            
System
.
err
.
println
(
“EOF”
);

            buffer 
=
 EOF
;

            n 
=
 

1
;

        
}

    
}

    
/**

     * Returns true if this binary input stream exists.

     *

     * 
@return
 {
@code
 true} if this binary input stream exists;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 exists
()
  
{

        
return
 in 
!=
 
null
;

    
}

   
/**

     * Returns true if this binary input stream is empty.

     *

     * 
@return
 {
@code
 true} if this binary input stream is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 buffer 
==
 EOF
;

    
}

   
/**

     * Reads the next bit of data from this binary input stream and return as a boolean.

     *

     * 
@return
 the next bit of data from this binary input stream as a {
@code
 boolean}

     * 
@throws
 NoSuchElementException if this binary input stream is empty

     */

    
public
 
boolean
 readBoolean
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        n

;

        
boolean
 bit 
=
 
((
buffer 
>>
 n
)
 
&
 
1
)
 
==
 
1
;

        
if
 
(

==
 
0
)
 fillBuffer
();

        
return
 bit
;

    
}

   
/**

     * Reads the next 8 bits from this binary input stream and return as an 8-bit char.

     *

     * 
@return
 the next 8 bits of data from this binary input stream as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than 8 bits available

     */

    
public
 
char
 readChar
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        
// special case when aligned byte

        
if
 
(

==
 
8
)
 
{

            
int
 x 
=
 buffer
;

            fillBuffer
();

            
return
 
(
char
)
 
(

&
 
0xff
);

        
}

        
// combine last N bits of current buffer with first 8-N bits of new buffer

        
int
 x 
=
 buffer
;

        x 
<<=   ( 8   -  n );          int  oldN  =  n ;         fillBuffer ();          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );         n  =  oldN ;         x  |=   ( buffer  >>>
 n
);

        
return
 
(
char
)
 
(

&
 
0xff
);

        
// the above code doesn’t quite work for the last character if N = 8

        
// because buffer will be -1

    
}

   
/**

     * Reads the next r bits from this binary input stream and return as an r-bit character.

     *

     * 
@param
  r number of bits to read

     * 
@return
 the next {
@code
 r} bits of data from this binary input streamt as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than {
@code
 r} bits available

     * 
@throws
 IllegalArgumentException unless {
@code
 1 <= r <= 16}      */      public   char  readChar ( int  r )   {          if   ( r  <   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 8 case

        
if
 
(

==
 
8
)
 
return
 readChar
();

        
char
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the remaining bytes of data from this binary input stream and return as a string.       *      *  @return  the remaining bytes of data from this binary input stream as a { @code  String}      *  @throws  NoSuchElementException if this binary input stream is empty or if the number of bits      *         available is not a multiple of 8 (byte-aligned)      */      public   String  readString ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );          StringBuilder  sb  =   new   StringBuilder ();          while   ( ! isEmpty ())   {              char  c  =  readChar ();             sb . append ( c );          }          return  sb . toString ();      }     /**      * Reads the next 16 bits from this binary input stream and return as a 16-bit short.      *      *  @return  the next 16 bits of data from this binary input stream as a { @code  short}      *  @throws  NoSuchElementException if there are fewer than 16 bits available      */      public   short  readShort ()   {          short  x  =   0 ;          for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 32 bits from this binary input stream and return as a 32-bit int.      *      *  @return  the next 32 bits of data from this binary input stream as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than 32 bits available      */      public   int  readInt ()   {          int  x  =   0 ;          for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next r bits from this binary input stream return as an r-bit int.      *      *  @param   r number of bits to read      *  @return  the next { @code  r} bits of data from this binary input stream as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than r bits available      *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}      */      public   int  readInt ( int  r )   {          if   ( r  <   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 32 case

        
if
 
(

==
 
32
)
 
return
 readInt
();

        
int
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the next 64 bits from this binary input stream and return as a 64-bit long.      *      *  @return  the next 64 bits of data from this binary input stream as a { @code  long}      *  @throws  NoSuchElementException if there are fewer than 64 bits available      */      public   long  readLong ()   {          long  x  =   0 ;          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 64 bits from this binary input stream and return as a 64-bit double.      *      *  @return  the next 64 bits of data from this binary input stream as a { @code  double}      *  @throws  NoSuchElementException if there are fewer than 64 bits available      */      public   double  readDouble ()   {          return   Double . longBitsToDouble ( readLong ());      }     /**      * Reads the next 32 bits from this binary input stream and return as a 32-bit float.      *      *  @return  the next 32 bits of data from this binary input stream as a { @code  float}      *  @throws  NoSuchElementException if there are fewer than 32 bits available      */      public   float  readFloat ()   {          return   Float . intBitsToFloat ( readInt ());      }     /**      * Reads the next 8 bits from this binary input stream and return as an 8-bit byte.      *      *  @return  the next 8 bits of data from this binary input stream as a { @code  byte}      *  @throws  NoSuchElementException if there are fewer than 8 bits available      */      public   byte  readByte ()   {          char  c  =  readChar ();          return   ( byte )   ( c  &   0xff );      }          /**      * Unit tests the { @code  BinaryIn} data type.      * Reads the name of a file or URL (first command-line argument)      * and writes it to a file (second command-line argument).      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          BinaryIn   in   =   new   BinaryIn ( args [ 0 ]);          BinaryOut  out  =   new   BinaryOut ( args [ 1 ]);          // read one 8-bit char at a time          while   ( ! in . isEmpty ())   {              char  c  =  in . readChar ();             out . write ( c );          }         out . flush ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinaryInsertion.java edu/princeton/cs/algs4/BinaryInsertion.java /******************************************************************************  *  Compilation:  javac BinaryInsertion.java  *  Execution:    java BinaryInsertion < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt  *                https://algs4.cs.princeton.edu/21elementary/words3.txt  *    *  Sorts a sequence of strings from standard input using   *  binary insertion sort with half exchanges.  *  *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java BinaryInsertion < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *  *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *  *  % java BinaryInsertion < words3.txt  *  all bad bed bug dad ... yes yet zoo   [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BinaryInsertion} class provides a static method for sorting an  *  array using an optimized binary insertion sort with half exchanges.  *  

 *  In the worst case, this implementation makes

 *  ~ n log2n compares to sort an array of length

 *  n. However, in the worst case, the running time is

 *  Θ(n2) because the number of array accesses

 *  can be quadratic.

 *  As such, it is not suitable for sorting large arrays

 *  (unless the number of inversions is small).

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(1) extra memory (not including the input array).

 *  

 *  For additional documentation,

 *  see Section 2.1

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Ivan Pesin

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BinaryInsertion
 
{

    
// This class should not be instantiated.

    
private
 
BinaryInsertion
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              // binary search to determine index j at which to insert a[i]              Comparable  v  =  a [ i ];              int  lo  =   0 ,  hi  =  i ;              while   ( lo  <  hi )   {                  int  mid  =  lo  +   ( hi  -  lo )   /   2 ;                    if   ( less ( v ,  a [ mid ]))  hi  =  mid ;                  else                  lo  =  mid  +   1 ;              }              // insetion sort with "half exchanges"              // (insert a[i] at index j and shift a[j], ..., a[i-1] to right)              for   ( int  j  =  i ;  j  >
 lo
;
 

j
)

                a
[
j
]
 
=
 a
[
j

1
];

            a
[
lo
]
 
=
 v
;

        
}

        
assert
 isSorted
(
a
);

    
}

   
/***************************************************************************

    *  Helper sorting function.

    ***************************************************************************/

    

    
// is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length  -   1 );      }      // is the array sorted from a[lo] to a[hi]      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo + 1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; insertion sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          BinaryInsertion . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinaryOut.java edu/princeton/cs/algs4/BinaryOut.java /******************************************************************************  *  Compilation:  javac BinaryOut.java  *  Execution:    java BinaryOut  *  Dependencies: none  *  *  Write binary data to an output stream, either one 1-bit boolean,  *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,  *  or one 64-bit long at a time. The output stream can be standard  *  output, a file, an OutputStream or a Socket.  *  *  The bytes written are not aligned.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . io . BufferedOutputStream ; import  java . io . FileOutputStream ; import  java . io . IOException ; import  java . io . OutputStream ; import  java . net . Socket ; /**  *  Binary output. This class provides methods for converting

 *  primtive type variables ({
@code
 boolean}, {
@code
 byte}, {
@code
 char},

 *  {
@code
 int}, {
@code
 long}, {
@code
 float}, and {
@code
 double})

 *  to sequences of bits and writing them to an output stream.

 *  The output stream can be standard output, a file, an OutputStream or a Socket.

 *  Uses big-endian (most-significant byte first).

 *  

 *  The client must {
@code
 flush()} the output stream when finished writing bits.

 *  

 *  The client should not intermix calls to {
@code
 BinaryOut} with calls

 *  to {
@code
 Out}; otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryOut
 
{

    
private
 
BufferedOutputStream
 out
;
  
// the output stream

    
private
 
int
 buffer
;
                
// 8-bit buffer of bits to write out

    
private
 
int
 n
;
                     
// number of bits remaining in buffer

   
/**

     * Initializes a binary output stream from standard output.

     */

    
public
 
BinaryOut
()
 
{

        out 
=
 
new
 
BufferedOutputStream
(
System
.
out
);

    
}

   
/**

     * Initializes a binary output stream from an {
@code
 OutputStream}.

     * 
@param
 os the {
@code
 OutputStream}

     */

    
public
 
BinaryOut
(
OutputStream
 os
)
 
{

        out 
=
 
new
 
BufferedOutputStream
(
os
);

    
}

   
/**

     * Initializes a binary output stream from a file.

     * 
@param
 filename the name of the file

     */

    
public
 
BinaryOut
(
String
 filename
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 
new
 
FileOutputStream
(
filename
);

            out 
=
 
new
 
BufferedOutputStream
(
os
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes a binary output stream from a socket.

     * 
@param
 socket the socket

     */

    
public
 
BinaryOut
(
Socket
 socket
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 socket
.
getOutputStream
();

            out 
=
 
new
 
BufferedOutputStream
(
os
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Writes the specified bit to the binary output stream.

     * 
@param
 x the bit

     */

    
private
 
void
 writeBit
(
boolean
 x
)
 
{

        
// add bit to buffer

        buffer 
<<=   1 ;          if   ( x )  buffer  |=   1 ;          // if buffer is full (8 bits), write out as a single byte         n ++ ;          if   ( n  ==   8 )  clearBuffer ();      }       /**      * Writes the 8-bit byte to the binary output stream.      *  @param  x the byte      */      private   void  writeByte ( int  x )   {          assert  x  >=
 
0
 
&&
 x 
<   256 ;          // optimized if byte-aligned          if   ( n  ==   0 )   {              try   {                 out . write ( x );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }              return ;          }          // otherwise write one bit at a time          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(
8
 

 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

    
// write out any remaining bits in buffer to the binary output stream, padding with 0s

    
private
 
void
 clearBuffer
()
 
{

        
if
 
(

==
 
0
)
 
return
;

        
if
 
(

>
 
0
)
 buffer 
<<=   ( 8   -  n );          try   {             out . write ( buffer );          }          catch   ( IOException  e )   {             e . printStackTrace ();          }         n  =   0 ;         buffer  =   0 ;      }     /**      * Flushes the binary output stream, padding 0s if number of bits written so far      * is not a multiple of 8.      */      public   void  flush ()   {         clearBuffer ();          try   {             out . flush ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Flushes and closes the binary output stream.      * Once it is closed, bits can no longer be written.      */      public   void  close ()   {         flush ();          try   {             out . close ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Writes the specified bit to the binary output stream.      *  @param  x the { @code  boolean} to write      */      public   void  write ( boolean  x )   {         writeBit ( x );      }       /**      * Writes the 8-bit byte to the binary output stream.      *  @param  x the { @code  byte} to write.      */      public   void  write ( byte  x )   {         writeByte ( x  &   0xff );      }     /**      * Writes the 32-bit int to the binary output stream.      *  @param  x the { @code  int} to write      */      public   void  write ( int  x )   {         writeByte (( x  >>>
 
24
)
 
&
 
0xff
);

        writeByte
((

>>>
 
16
)
 
&
 
0xff
);

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the r-bit int to the binary output stream.

     *

     * 
@param
  x the {
@code
 int} to write

     * 
@param
  r the number of relevant bits in the char

     * 
@throws
 IllegalArgumentException unless {
@code
 r} is between 1 and 32

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is between 0 and 2r – 1

     */

    
public
 
void
 write
(
int
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
32
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the 64-bit double to the binary output stream.

     * 
@param
 x the {
@code
 double} to write

     */

    
public
 
void
 write
(
double
 x
)
 
{

        write
(
Double
.
doubleToRawLongBits
(
x
));

    
}

   
/**

     * Writes the 64-bit long to the binary output stream.

     * 
@param
 x the {
@code
 long} to write

     */

    
public
 
void
 write
(
long
 x
)
 
{

        writeByte
((
int
)
 
((

>>>
 
56
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
48
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
40
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
32
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
24
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
16
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
8
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
0
)
 
&
 
0xff
));

    
}

   
/**

     * Writes the 32-bit float to the binary output stream.

     * 
@param
 x the {
@code
 float} to write

     */

    
public
 
void
 write
(
float
 x
)
 
{

        write
(
Float
.
floatToRawIntBits
(
x
));

    
}

   
/**

     * Write the 16-bit int to the binary output stream.

     * 
@param
 x the {
@code
 short} to write.

     */

    
public
 
void
 write
(
short
 x
)
 
{

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the 8-bit char to the binary output stream.

     *

     * 
@param
  x the {
@code
 char} to write

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is betwen 0 and 255

     */

    
public
 
void
 write
(
char
 x
)
 
{

        
if
 
(

<   0   ||  x  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal 8-bit char = ”
 
+
 x
);

        writeByte
(
x
);

    
}

   
/**

     * Writes the r-bit char to the binary output stream.

     *

     * 
@param
  x the {
@code
 char} to write

     * 
@param
  r the number of relevant bits in the char

     * 
@throws
 IllegalArgumentException unless {
@code
 r} is between 1 and 16

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is between 0 and 2r – 1

     */

    
public
 
void
 write
(
char
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
8
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the string of 8-bit characters to the binary output stream.

     *

     * 
@param
  s the {
@code
 String} to write

     * 
@throws
 IllegalArgumentException if any character in the string is not

     *         between 0 and 255

     */

    
public
 
void
 write
(
String
 s
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ));      }     /**      * Writes the string of r-bit characters to the binary output stream.      *  @param   s the { @code  String} to write      *  @param   r the number of relevants bits in each character      *  @throws  IllegalArgumentException unless r is between 1 and 16      *  @throws  IllegalArgumentException if any character in the string is not      *         between 0 and 2r – 1

     */

    
public
 
void
 write
(
String
 s
,
 
int
 r
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ),  r );      }     /**      * Test client. Read bits from standard input and write to the file      * specified on command line.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // create binary output stream to write to file          String  filename  =  args [ 0 ];          BinaryOut  out  =   new   BinaryOut ( filename );          BinaryIn   in   =   new   BinaryIn ();          // read from standard input and write to file          while   ( ! in . isEmpty ())   {              char  c  =  in . readChar ();             out . write ( c );          }         out . flush ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinarySearch.java edu/princeton/cs/algs4/BinarySearch.java /******************************************************************************  *  Compilation:  javac BinarySearch.java  *  Execution:    java BinarySearch whitelist.txt < input.txt  *  Dependencies: In.java StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/11model/tinyW.txt  *                https://algs4.cs.princeton.edu/11model/tinyT.txt  *                https://algs4.cs.princeton.edu/11model/largeW.txt  *                https://algs4.cs.princeton.edu/11model/largeT.txt  *  *  % java BinarySearch tinyW.txt < tinyT.txt  *  50  *  99  *  13  *  *  % java BinarySearch largeW.txt < largeT.txt | more  *  499569  *  984875  *  295754  *  207807  *  140925  *  161828  *  [367,966 total values]  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  *  The { @code  BinarySearch} class provides a static method for binary  *  searching for an integer in a sorted array of integers.  *  

 *  The indexOf operations takes logarithmic time in the worst case.

 *  

 *  For additional documentation, see Section 1.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BinarySearch
 
{

    
/**

     * This class should not be instantiated.

     */

    
private
 
BinarySearch
()
 
{
 
}

    
/**

     * Returns the index of the specified key in the specified array.

     *

     * 
@param
  a the array of integers, must be sorted in ascending order

     * 
@param
  key the search key

     * 
@return
 index of key in array {
@code
 a} if present; {
@code
 -1} otherwise

     */

    
public
 
static
 
int
 indexOf
(
int
[]
 a
,
 
int
 key
)
 
{

        
int
 lo 
=
 
0
;

        
int
 hi 
=
 a
.
length 

 
1
;

        
while
 
(
lo 
<=  hi )   {              // Key is in a[lo..hi] or not present.              int  mid  =  lo  +   ( hi  -  lo )   /   2 ;              if        ( key  <  a [ mid ])  hi  =  mid  -   1 ;              else   if   ( key  >
 a
[
mid
])
 lo 
=
 mid 
+
 
1
;

            
else
 
return
 mid
;

        
}

        
return
 

1
;

    
}

    
/**

     * Returns the index of the specified key in the specified array.

     * This function is poorly named because it does not give the rank

     * if the array has duplicate keys or if the key is not in the array.

     *

     * 
@param
  key the search key

     * 
@param
  a the array of integers, must be sorted in ascending order

     * 
@return
 index of key in array {
@code
 a} if present; {
@code
 -1} otherwise

     * 
@deprecated
 Replaced by {
@link
 #indexOf(int[], int)}.

     */

    @
Deprecated

    
public
 
static
 
int
 rank
(
int
 key
,
 
int
[]
 a
)
 
{

        
return
 indexOf
(
a
,
 key
);

    
}

    
/**

     * Reads in a sequence of integers from the whitelist file, specified as

     * a command-line argument; reads in integers from standard input;

     * prints to standard output those integers that do not appear in the file.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// read the integers from a file

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
[]
 whitelist 
=
 in
.
readAllInts
();

        
// sort the array

        
Arrays
.
sort
(
whitelist
);

        
// read integer key from standard input; print if not in whitelist

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
int
 key 
=
 
StdIn
.
readInt
();

            
if
 
(
BinarySearch
.
indexOf
(
whitelist
,
 key
)
 
==
 

1
)

                
StdOut
.
println
(
key
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BinarySearchST.java
edu/princeton/cs/algs4/BinarySearchST.java
/******************************************************************************

 *  Compilation:  javac BinarySearchST.java

 *  Execution:    java BinarySearchST

 *  Dependencies: StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyST.txt  

 *  

 *  Symbol table implementation with binary search in an ordered array.

 *

 *  % more tinyST.txt

 *  S E A R C H E X A M P L E

 *  

 *  % java BinarySearchST < tinyST.txt  *  A 8  *  C 4  *  E 12  *  H 5  *  L 11  *  M 9  *  P 10  *  R 3  *  S 0  *  X 7  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  BST} class represents an ordered symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides ordered methods for finding the minimum,

 *  maximumfloorselect, and ceiling.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  

 *  This implementation uses a sorted array.

 *  The put and remove operations take Θ(n)

 *  time in the worst case.

 *  The containsceilingfloor,

 *  and rank operations take Θ(log n) time in the worst

 *  case.

 *  The sizeis-emptyminimummaximum,

 *  and select operations take Θ(1) time.

 *  Construction takes Θ(1) time.

 *  

 *  For alternative implementations of the symbol table API,

 *  see {
@link
 ST}, {
@link
 BST}, {
@link
 SequentialSearchST}, {
@link
 RedBlackBST},

 *  {
@link
 SeparateChainingHashST}, and {
@link
 LinearProbingHashST},

 *  For additional documentation,

 *  see Section 3.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
BinarySearchST
< Key   extends   Comparable < Key >
,
 
Value
>
 
{

    
private
 
static
 
final
 
int
 INIT_CAPACITY 
=
 
2
;

    
private
 
Key
[]
 keys
;

    
private
 
Value
[]
 vals
;

    
private
 
int
 n 
=
 
0
;

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
BinarySearchST
()
 
{

        
this
(
INIT_CAPACITY
);

    
}

    
/**

     * Initializes an empty symbol table with the specified initial capacity.

     * 
@param
 capacity the maximum capacity

     */

    
public
 
BinarySearchST
(
int
 capacity
)
 
{
 

        keys 
=
 
(
Key
[])
 
new
 
Comparable
[
capacity
];
 

        vals 
=
 
(
Value
[])
 
new
 
Object
[
capacity
];
 

    
}
   

    
// resize the underlying arrays

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>=
 n
;

        
Key
[]
   tempk 
=
 
(
Key
[])
   
new
 
Comparable
[
capacity
];

        
Value
[]
 tempv 
=
 
(
Value
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             tempk [ i ]   =  keys [ i ];             tempv [ i ]   =  vals [ i ];          }         vals  =  tempv ;         keys  =  tempk ;      }      /**      * Returns the number of key-value pairs in this symbol table.      *      *  @return  the number of key-value pairs in this symbol table      */      public   int  size ()   {          return  n ;      }      /**      * Returns true if this symbol table is empty.      *      *  @return  { @code  true} if this symbol table is empty;      *         { @code  false} otherwise      */      public   boolean  isEmpty ()   {          return  size ()   ==   0 ;      }      /**      * Does this symbol table contain the given key?      *      *  @param   key the key      *  @return  { @code  true} if this symbol table contains { @code  key} and      *         { @code  false} otherwise      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   boolean  contains ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );          return  get ( key )   !=   null ;      }      /**      * Returns the value associated with the given key in this symbol table.      *      *  @param   key the key      *  @return  the value associated with the given key if the key is in the symbol table      *         and { @code  null} if the key is not in the symbol table      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Value  get ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );            if   ( isEmpty ())   return   null ;          int  i  =  rank ( key );            if   ( i  <  n  &&  keys [ i ]. compareTo ( key )   ==   0 )   return  vals [ i ];          return   null ;      }        /**      * Returns the number of keys in this symbol table strictly less than { @code  key}.      *      *  @param   key the key      *  @return  the number of keys in the symbol table strictly less than { @code  key}      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   int  rank ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );            int  lo  =   0 ,  hi  =  n - 1 ;            while   ( lo  <=  hi )   {                int  mid  =  lo  +   ( hi  -  lo )   /   2 ;                int  cmp  =  key . compareTo ( keys [ mid ]);              if        ( cmp  <   0 )  hi  =  mid  -   1 ;                else   if   ( cmp  >
 
0
)
 lo 
=
 mid 
+
 
1
;
 

            
else
 
return
 mid
;
 

        
}
 

        
return
 lo
;

    
}
 

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting the old 

     * value with the new value if the symbol table already contains the specified key.

     * Deletes the specified key (and its associated value) from this symbol table

     * if the specified value is {
@code
 null}.

     *

     * 
@param
  key the key

     * 
@param
  val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
  
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to put() is null”
);
 

        
if
 
(
val 
==
 
null
)
 
{

            delete
(
key
);

            
return
;

        
}

        
int
 i 
=
 rank
(
key
);

        
// key is already in table

        
if
 
(

<  n  &&  keys [ i ]. compareTo ( key )   ==   0 )   {             vals [ i ]   =  val ;              return ;          }          // insert new key-value pair          if   ( n  ==  keys . length )  resize ( 2 * keys . length );          for   ( int  j  =  n ;  j  >
 i
;
 j

)
  
{

            keys
[
j
]
 
=
 keys
[
j

1
];

            vals
[
j
]
 
=
 vals
[
j

1
];

        
}

        keys
[
i
]
 
=
 key
;

        vals
[
i
]
 
=
 val
;

        n
++
;

        
assert
 check
();

    
}
 

    
/**

     * Removes the specified key and associated value from this symbol table

     * (if the key is in the symbol table).

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to delete() is null”
);
 

        
if
 
(
isEmpty
())
 
return
;

        
// compute rank

        
int
 i 
=
 rank
(
key
);

        
// key not in table

        
if
 
(

==
 n 
||
 keys
[
i
].
compareTo
(
key
)
 
!=
 
0
)
 
{

            
return
;

        
}

        
for
 
(
int
 j 
=
 i
;
 j 
<  n - 1 ;  j ++ )    {             keys [ j ]   =  keys [ j + 1 ];             vals [ j ]   =  vals [ j + 1 ];          }         n -- ;         keys [ n ]   =   null ;    // to avoid loitering         vals [ n ]   =   null ;          // resize if 1/4 full          if   ( n  >
 
0
 
&&
 n 
==
 keys
.
length
/
4
)
 resize
(
keys
.
length
/
2
);

        
assert
 check
();

    
}
 

    
/**

     * Removes the smallest key and associated value from this symbol table.

     *

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Symbol table underflow error”
);

        delete
(
min
());

    
}

    
/**

     * Removes the largest key and associated value from this symbol table.

     *

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMax
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Symbol table underflow error”
);

        delete
(
max
());

    
}

   
/***************************************************************************

    *  Ordered symbol table methods.

    ***************************************************************************/

   
/**

     * Returns the smallest key in this symbol table.

     *

     * 
@return
 the smallest key in this symbol table

     * 
@throws
 NoSuchElementException if this symbol table is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called min() with empty symbol table”
);

        
return
 keys
[
0
];
 

    
}

    
/**

     * Returns the largest key in this symbol table.

     *

     * 
@return
 the largest key in this symbol table

     * 
@throws
 NoSuchElementException if this symbol table is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called max() with empty symbol table”
);

        
return
 keys
[
n

1
];

    
}

    
/**

     * Return the kth smallest key in this symbol table.

     *

     * 
@param
  k the order statistic

     * 
@return
 the {
@code
 k}th smallest key in this symbol table

     * 
@throws
 IllegalArgumentException unless {
@code
 k} is between 0 and

     *        n–1

     */

    
public
 
Key
 select
(
int
 k
)
 
{

        
if
 
(

<   0   ||  k  >=
 size
())
 
{

            
throw
 
new
 
IllegalArgumentException
(
“called select() with invalid argument: ”
 
+
 k
);

        
}

        
return
 keys
[
k
];

    
}

    
/**

     * Returns the largest key in this symbol table less than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the largest key in this symbol table less than or equal to {
@code
 key}

     * 
@throws
 NoSuchElementException if there is no such key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 floor
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to floor() is null”
);
 

        
int
 i 
=
 rank
(
key
);

        
if
 
(

<  n  &&  key . compareTo ( keys [ i ])   ==   0 )   return  keys [ i ];          if   ( i  ==   0 )   return   null ;          else   return  keys [ i - 1 ];      }      /**      * Returns the smallest key in this symbol table greater than or equal to { @code  key}.      *      *  @param   key the key      *  @return  the smallest key in this symbol table greater than or equal to { @code  key}      *  @throws  NoSuchElementException if there is no such key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Key  ceiling ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );            int  i  =  rank ( key );          if   ( i  ==  n )   return   null ;            else   return  keys [ i ];      }      /**      * Returns the number of keys in this symbol table in the specified range.      *      *  @param  lo minimum endpoint      *  @param  hi maximum endpoint      *  @return  the number of keys in this symbol table between { @code  lo}       *         (inclusive) and { @code  hi} (inclusive)      *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}      *         is { @code  null}      */      public   int  size ( Key  lo ,   Key  hi )   {          if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to size() is null" );            if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to size() is null" );            if   ( lo . compareTo ( hi )   >
 
0
)
 
return
 
0
;

        
if
 
(
contains
(
hi
))
 
return
 rank
(
hi
)
 

 rank
(
lo
)
 
+
 
1
;

        
else
              
return
 rank
(
hi
)
 

 rank
(
lo
);

    
}

    
/**

     * Returns all keys in this symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     *

     * 
@return
 all keys in this symbol table

     */

    
public
 
Iterable
< Key >
 keys
()
 
{

        
return
 keys
(
min
(),
 max
());

    
}

    
/**

     * Returns all keys in this symbol table in the given range,

     * as an {
@code
 Iterable}.

     *

     * 
@param
 lo minimum endpoint

     * 
@param
 hi maximum endpoint

     * 
@return
 all keys in this symbol table between {
@code
 lo} 

     *         (inclusive) and {
@code
 hi} (inclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *         is {
@code
 null}

     */

    
public
 
Iterable
< Key >
 keys
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to keys() is null”
);
 

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to keys() is null”
);
 

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();
 

        
if
 
(
lo
.
compareTo
(
hi
)
 
>
 
0
)
 
return
 queue
;

        
for
 
(
int
 i 
=
 rank
(
lo
);
 i 
<  rank ( hi );  i ++ )               queue . enqueue ( keys [ i ]);          if   ( contains ( hi ))  queue . enqueue ( keys [ rank ( hi )]);          return  queue ;        }     /***************************************************************************     *  Check internal invariants.     ***************************************************************************/      private   boolean  check ()   {          return  isSorted ()   &&  rankCheck ();      }      // are the items in the array in ascending order?      private   boolean  isSorted ()   {          for   ( int  i  =   1 ;  i  <  size ();  i ++ )              if   ( keys [ i ]. compareTo ( keys [ i - 1 ])   <   0 )   return   false ;          return   true ;      }      // check that rank(select(i)) = i      private   boolean  rankCheck ()   {          for   ( int  i  =   0 ;  i  <  size ();  i ++ )              if   ( i  !=  rank ( select ( i )))   return   false ;          for   ( int  i  =   0 ;  i  <  size ();  i ++ )              if   ( keys [ i ]. compareTo ( select ( rank ( keys [ i ])))   !=   0 )   return   false ;          return   true ;      }      /**      * Unit tests the { @code  BinarySearchST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            BinarySearchST < String ,   Integer >
 st 
=
 
new
 
BinarySearchST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
for
 
(
String
 s 
:
 st
.
keys
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BinaryStdIn.java
edu/princeton/cs/algs4/BinaryStdIn.java
/******************************************************************************

 *  Compilation:  javac BinaryStdIn.java

 *  Execution:    java BinaryStdIn < input > output

 *  Dependencies: none             

 *  

 *  Supports reading binary data from standard input.

 *

 *  % java BinaryStdIn < input  > output

 *  % diff input  output

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
io
.
BufferedInputStream
;

import
 java
.
io
.
IOException
;

import
 java
.
util
.
NoSuchElementException
;

/**

 *  Binary standard input. This class provides methods for reading

 *  in bits from standard input, either one bit at a time (as a {
@code
 boolean}),

 *  8 bits at a time (as a {
@code
 byte} or {
@code
 char}),

 *  16 bits at a time (as a {
@code
 short}), 32 bits at a time

 *  (as an {
@code
 int} or {
@code
 float}), or 64 bits at a time (as a

 *  {
@code
 double} or {
@code
 long}).

 *  

 *  All primitive types are assumed to be represented using their 

 *  standard Java representations, in big-endian (most significant

 *  byte first) order.

 *  

 *  The client should not intermix calls to {
@code
 BinaryStdIn} with calls

 *  to {
@code
 StdIn} or {
@code
 System.in};

 *  otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryStdIn
 
{

    
private
 
static
 
final
 
int
 EOF 
=
 

1
;
      
// end of file

    
private
 
static
 
BufferedInputStream
 in
;
  
// input stream

    
private
 
static
 
int
 buffer
;
              
// one character buffer

    
private
 
static
 
int
 n
;
                   
// number of bits left in buffer

    
private
 
static
 
boolean
 isInitialized
;
   
// has BinaryStdIn been called for first time?

    
// don’t instantiate

    
private
 
BinaryStdIn
()
 
{
 
}

    
// fill buffer

    
private
 
static
 
void
 initialize
()
 
{

        in 
=
 
new
 
BufferedInputStream
(
System
.
in
);

        buffer 
=
 
0
;

        n 
=
 
0
;

        fillBuffer
();

        isInitialized 
=
 
true
;

    
}

    
private
 
static
 
void
 fillBuffer
()
 
{

        
try
 
{

            buffer 
=
 in
.
read
();

            n 
=
 
8
;

        
}

        
catch
 
(
IOException
 e
)
 
{

            
System
.
out
.
println
(
“EOF”
);

            buffer 
=
 EOF
;

            n 
=
 

1
;

        
}

    
}

   
/**

     * Close this input stream and release any associated system resources.

     */

    
public
 
static
 
void
 close
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
try
 
{

            in
.
close
();

            isInitialized 
=
 
false
;

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalStateException
(
“Could not close BinaryStdIn”
,
 ioe
);

        
}

    
}

   
/**

     * Returns true if standard input is empty.

     * 
@return
 true if and only if standard input is empty

     */

    
public
 
static
 
boolean
 isEmpty
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
return
 buffer 
==
 EOF
;

    
}

   
/**

     * Reads the next bit of data from standard input and return as a boolean.

     *

     * 
@return
 the next bit of data from standard input as a {
@code
 boolean}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
boolean
 readBoolean
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        n

;

        
boolean
 bit 
=
 
((
buffer 
>>
 n
)
 
&
 
1
)
 
==
 
1
;

        
if
 
(

==
 
0
)
 fillBuffer
();

        
return
 bit
;

    
}

   
/**

     * Reads the next 8 bits from standard input and return as an 8-bit char.

     * Note that {
@code
 char} is a 16-bit type;

     * to read the next 16 bits as a char, use {
@code
 readChar(16)}.

     *

     * 
@return
 the next 8 bits of data from standard input as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than 8 bits available on standard input

     */

    
public
 
static
 
char
 readChar
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        
// special case when aligned byte

        
if
 
(

==
 
8
)
 
{

            
int
 x 
=
 buffer
;

            fillBuffer
();

            
return
 
(
char
)
 
(

&
 
0xff
);

        
}

        
// combine last n bits of current buffer with first 8-n bits of new buffer

        
int
 x 
=
 buffer
;

        x 
<<=   ( 8   -  n );          int  oldN  =  n ;         fillBuffer ();          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );         n  =  oldN ;         x  |=   ( buffer  >>>
 n
);

        
return
 
(
char
)
 
(

&
 
0xff
);

        
// the above code doesn’t quite work for the last character if n = 8

        
// because buffer will be -1, so there is a special case for aligned byte

    
}

   
/**

     * Reads the next r bits from standard input and return as an r-bit character.

     *

     * 
@param
  r number of bits to read.

     * 
@return
 the next r bits of data from standard input as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than {
@code
 r} bits available on standard input

     * 
@throws
 IllegalArgumentException unless {
@code
 1 <= r <= 16}      */      public   static   char  readChar ( int  r )   {          if   ( r  <   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 8 case

        
if
 
(

==
 
8
)
 
return
 readChar
();

        
char
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the remaining bytes of data from standard input and return as a string.       *      *  @return  the remaining bytes of data from standard input as a { @code  String}      *  @throws  NoSuchElementException if standard input is empty or if the number of bits      *         available on standard input is not a multiple of 8 (byte-aligned)      */      public   static   String  readString ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );          StringBuilder  sb  =   new   StringBuilder ();          while   ( ! isEmpty ())   {              char  c  =  readChar ();             sb . append ( c );          }          return  sb . toString ();      }     /**      * Reads the next 16 bits from standard input and return as a 16-bit short.      *      *  @return  the next 16 bits of data from standard input as a { @code  short}      *  @throws  NoSuchElementException if there are fewer than 16 bits available on standard input      */      public   static   short  readShort ()   {          short  x  =   0 ;          for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 32 bits from standard input and return as a 32-bit int.      *      *  @return  the next 32 bits of data from standard input as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input      */      public   static   int  readInt ()   {          int  x  =   0 ;          for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next r bits from standard input and return as an r-bit int.      *      *  @param   r number of bits to read.      *  @return  the next r bits of data from standard input as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than { @code  r} bits available on standard input      *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}      */      public   static   int  readInt ( int  r )   {          if   ( r  <   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 32 case

        
if
 
(

==
 
32
)
 
return
 readInt
();

        
int
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the next 64 bits from standard input and return as a 64-bit long.      *      *  @return  the next 64 bits of data from standard input as a { @code  long}      *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input      */      public   static   long  readLong ()   {          long  x  =   0 ;          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 64 bits from standard input and return as a 64-bit double.      *      *  @return  the next 64 bits of data from standard input as a { @code  double}      *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input      */      public   static   double  readDouble ()   {          return   Double . longBitsToDouble ( readLong ());      }     /**      * Reads the next 32 bits from standard input and return as a 32-bit float.      *      *  @return  the next 32 bits of data from standard input as a { @code  float}      *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input      */      public   static   float  readFloat ()   {          return   Float . intBitsToFloat ( readInt ());      }     /**      * Reads the next 8 bits from standard input and return as an 8-bit byte.      *      *  @return  the next 8 bits of data from standard input as a { @code  byte}      *  @throws  NoSuchElementException if there are fewer than 8 bits available on standard input      */      public   static   byte  readByte ()   {          char  c  =  readChar ();          return   ( byte )   ( c  &   0xff );      }          /**      * Test client. Reads in a binary input file from standard input and writes      * it to standard output.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read one 8-bit char at a time          while   ( ! BinaryStdIn . isEmpty ())   {              char  c  =   BinaryStdIn . readChar ();              BinaryStdOut . write ( c );          }          BinaryStdOut . flush ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinaryStdOut.java edu/princeton/cs/algs4/BinaryStdOut.java /******************************************************************************  *  Compilation:  javac BinaryStdOut.java  *  Execution:    java BinaryStdOut  *  Dependencies: none  *  *  Write binary data to standard output, either one 1-bit boolean,  *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,  *  or one 64-bit long at a time.  *  *  The bytes written are not aligned.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . io . BufferedOutputStream ; import  java . io . IOException ; /**  *  Binary standard output. This class provides methods for converting

 *  primtive type variables ({
@code
 boolean}, {
@code
 byte}, {
@code
 char},

 *  {
@code
 int}, {
@code
 long}, {
@code
 float}, and {
@code
 double})

 *  to sequences of bits and writing them to standard output.

 *  Uses big-endian (most-significant byte first).

 *  

 *  The client must {
@code
 flush()} the output stream when finished writing bits.

 *  

 *  The client should not intermix calls to {
@code
 BinaryStdOut} with calls

 *  to {
@code
 StdOut} or {
@code
 System.out}; otherwise unexpected behavior 

 *  will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryStdOut
 
{

    
private
 
static
 
BufferedOutputStream
 out
;
  
// output stream (standard output)

    
private
 
static
 
int
 buffer
;
                
// 8-bit buffer of bits to write

    
private
 
static
 
int
 n
;
                     
// number of bits remaining in buffer

    
private
 
static
 
boolean
 isInitialized
;
     
// has BinaryStdOut been called for first time?

    
// don’t instantiate

    
private
 
BinaryStdOut
()
 
{
 
}

    
// initialize BinaryStdOut

    
private
 
static
 
void
 initialize
()
 
{

        out 
=
 
new
 
BufferedOutputStream
(
System
.
out
);

        buffer 
=
 
0
;

        n 
=
 
0
;

        isInitialized 
=
 
true
;

    
}

   
/**

     * Writes the specified bit to standard output.

     */

    
private
 
static
 
void
 writeBit
(
boolean
 bit
)
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
// add bit to buffer

        buffer 
<<=   1 ;          if   ( bit )  buffer  |=   1 ;          // if buffer is full (8 bits), write out as a single byte         n ++ ;          if   ( n  ==   8 )  clearBuffer ();      }       /**      * Writes the 8-bit byte to standard output.      */      private   static   void  writeByte ( int  x )   {          if   ( ! isInitialized )  initialize ();          assert  x  >=
 
0
 
&&
 x 
<   256 ;          // optimized if byte-aligned          if   ( n  ==   0 )   {              try   {                 out . write ( x );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }              return ;          }          // otherwise write one bit at a time          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(
8
 

 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

    
// write out any remaining bits in buffer to standard output, padding with 0s

    
private
 
static
 
void
 clearBuffer
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
if
 
(

==
 
0
)
 
return
;

        
if
 
(

>
 
0
)
 buffer 
<<=   ( 8   -  n );          try   {             out . write ( buffer );          }          catch   ( IOException  e )   {             e . printStackTrace ();          }         n  =   0 ;         buffer  =   0 ;      }     /**      * Flushes standard output, padding 0s if number of bits written so far      * is not a multiple of 8.      */      public   static   void  flush ()   {         clearBuffer ();          try   {             out . flush ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Flushes and closes standard output. Once standard output is closed, you can no      * longer write bits to it.      */      public   static   void  close ()   {         flush ();          try   {             out . close ();             isInitialized  =   false ;          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Writes the specified bit to standard output.      *  @param  x the { @code  boolean} to write.      */      public   static   void  write ( boolean  x )   {         writeBit ( x );      }       /**      * Writes the 8-bit byte to standard output.      *  @param  x the { @code  byte} to write.      */      public   static   void  write ( byte  x )   {         writeByte ( x  &   0xff );      }     /**      * Writes the 32-bit int to standard output.      *  @param  x the { @code  int} to write.      */      public   static   void  write ( int  x )   {         writeByte (( x  >>>
 
24
)
 
&
 
0xff
);

        writeByte
((

>>>
 
16
)
 
&
 
0xff
);

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the r-bit int to standard output.

     * 
@param
 x the {
@code
 int} to write.

     * 
@param
 r the number of relevant bits in the char.

     * 
@throws
 IllegalArgumentException if {
@code
 r} is not between 1 and 32.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
int
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
32
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
32
)
        
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

<   0   ||  x  >=
 
(
1
 
<<  r ))   throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the 64-bit double to standard output.

     * 
@param
 x the {
@code
 double} to write.

     */

    
public
 
static
 
void
 write
(
double
 x
)
 
{

        write
(
Double
.
doubleToRawLongBits
(
x
));

    
}

   
/**

     * Writes the 64-bit long to standard output.

     * 
@param
 x the {
@code
 long} to write.

     */

    
public
 
static
 
void
 write
(
long
 x
)
 
{

        writeByte
((
int
)
 
((

>>>
 
56
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
48
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
40
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
32
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
24
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
16
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
8
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
0
)
 
&
 
0xff
));

    
}

   
/**

     * Writes the 32-bit float to standard output.

     * 
@param
 x the {
@code
 float} to write.

     */

    
public
 
static
 
void
 write
(
float
 x
)
 
{

        write
(
Float
.
floatToRawIntBits
(
x
));

    
}

   
/**

     * Writes the 16-bit int to standard output.

     * 
@param
 x the {
@code
 short} to write.

     */

    
public
 
static
 
void
 write
(
short
 x
)
 
{

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the 8-bit char to standard output.

     * 
@param
 x the {
@code
 char} to write.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not betwen 0 and 255.

     */

    
public
 
static
 
void
 write
(
char
 x
)
 
{

        
if
 
(

<   0   ||  x  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal 8-bit char = ”
 
+
 x
);

        writeByte
(
x
);

    
}

   
/**

     * Writes the r-bit char to standard output.

     * 
@param
 x the {
@code
 char} to write.

     * 
@param
 r the number of relevant bits in the char.

     * 
@throws
 IllegalArgumentException if {
@code
 r} is not between 1 and 16.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
char
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
8
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the string of 8-bit characters to standard output.

     * 
@param
 s the {
@code
 String} to write.

     * 
@throws
 IllegalArgumentException if any character in the string is not

     * between 0 and 255.

     */

    
public
 
static
 
void
 write
(
String
 s
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ));      }     /**      * Writes the string of r-bit characters to standard output.      *  @param  s the { @code  String} to write.      *  @param  r the number of relevants bits in each character.      *  @throws  IllegalArgumentException if r is not between 1 and 16.      *  @throws  IllegalArgumentException if any character in the string is not      * between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
String
 s
,
 
int
 r
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ),  r );      }     /**      * Tests the methods in this class.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  m  =   Integer . parseInt ( args [ 0 ]);          // write n integers to binary standard output          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              BinaryStdOut . write ( i );          }          BinaryStdOut . flush ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BinomialMinPQ.java edu/princeton/cs/algs4/BinomialMinPQ.java /******************************************************************************  *  Compilation: javac BinomialMinPQ.java  *  Execution:  *    *  A binomial heap.  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . Comparator ; import  java . util . NoSuchElementException ; /**  *  The BinomialMinPQ class represents a priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum operations,   *  along with the merging of two heaps together.  *  It also supports methods for peeking at the minimum key,  *  testing if the priority queue is empty, and iterating through  *  the keys.  *  It is possible to build the priority queue using a Comparator.  *  If not, the natural order relation between the keys will be used.  *    *  This implementation uses a binomial heap.  *  The insert, delete-the-minimum, union, min-key  *  and size operations take logarithmic time.  *  The is-empty and constructor operations take constant time.  *   *   @author  Tristan Claverie  */ public   class   BinomialMinPQ < Key >
 
implements
 
Iterable
< Key >
 
{

    
private
 
Node
 head
;
                  
//head of the list of roots

    
private
 
final
 
Comparator
< Key >
 comp
;
 
//Comparator over the keys

    

    
//Represents a Node of a Binomial Tree

    
private
 
class
 
Node
 
{

        
Key
 key
;
                        
//Key contained by the Node

        
int
 order
;
                      
//The order of the Binomial Tree rooted by this Node

        
Node
 child
,
 sibling
;
            
//child and sibling of this Node

    
}

    

    
/**

     * Initializes an empty priority queue

     * Worst case is O(1)

     */

    
public
 
BinomialMinPQ
()
 
{

        comp 
=
 
new
 
MyComparator
();

    
}

    

    
/**

     * Initializes an empty priority queue using the given Comparator

     * Worst case is O(1)

     * 
@param
 C a comparator over the keys

     */

    
public
 
BinomialMinPQ
(
Comparator
< Key >
 C
)
 
{

        comp 
=
 C
;

    
}

    

    
/**

     * Initializes a priority queue with given keys

     * Worst case is O(n*log(n))

     * 
@param
 a an array of keys

     */

    
public
 
BinomialMinPQ
(
Key
[]
 a
)
 
{

        comp 
=
 
new
 
MyComparator
();

        
for
 
(
Key
 k 
:
 a
)
 insert
(
k
);

    
}

    

    
/**

     * Initializes a priority queue with given keys using the given Comparator

     * Worst case is O(n*log(n))

     * 
@param
 C a comparator over the keys

     * 
@param
 a an array of keys

     */

    
public
 
BinomialMinPQ
(
Comparator
< Key >
 C
,
 
Key
[]
 a
)
 
{

        comp 
=
 C
;

        
for
 
(
Key
 k 
:
 a
)
 insert
(
k
);

    
}

    
/**

     * Whether the priority queue is empty

     * Worst case is O(1)

     * 
@return
 true if the priority queue is empty, false if not

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 head 
==
 
null
;

    
}

    
/**

     * Number of elements currently on the priority queue

     * Worst case is O(log(n))

     * 
@throws
 java.lang.ArithmeticException if there are more than 2^63-1 elements in the queue

     * 
@return
 the number of elements on the priority queue

     */

    
public
 
int
 size
()
 
{

        
int
 result 
=
 
0
,
 tmp
;

        
for
 
(
Node
 node 
=
 head
;
 node 
!=
 
null
;
 node 
=
 node
.
sibling
)
 
{

            
if
 
(
node
.
order 
>
 
30
)
 
{
 
throw
 
new
 
ArithmeticException
(
“The number of elements cannot be evaluated, but the priority queue is still valid.”
);
 
}

            tmp 
=
 
1
 
<<  node . order ;             result  |=  tmp ;          }          return  result ;      }      /**      * Puts a Key in the heap      * Worst case is O(log(n))      *  @param  key a Key      */      public   void  insert ( Key  key )   {          Node  x  =   new   Node ();         x . key  =  key ;         x . order  =   0 ;          BinomialMinPQ < Key >
 H 
=
 
new
 
BinomialMinPQ
< Key >
();
 
//The Comparator oh the H heap is not used

        H
.
head 
=
 x
;

        
this
.
head 
=
 
this
.
union
(
H
).
head
;

    
}

    
/**

     * Get the minimum key currently in the queue

     * Worst case is O(log(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key currently in the priority queue

     */

    
public
 
Key
 minKey
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
Node
 min 
=
 head
;

        
Node
 current 
=
 head
;

        
while
 
(
current
.
sibling 
!=
 
null
)
 
{

            min 
=
 
(
greater
(
min
.
key
,
 current
.
sibling
.
key
))
 
?
 current 
:
 min
;

            current 
=
 current
.
sibling
;

        
}

        
return
 min
.
key
;

    
}

    
/**

     * Deletes the minimum key

     * Worst case is O(log(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key

     */

    
public
 
Key
 delMin
()
 
{

        
if
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
Node
 min 
=
 eraseMin
();

        
Node
 x 
=
 
(
min
.
child 
==
 
null
)
 
?
 min 
:
 min
.
child
;

        
if
 
(
min
.
child 
!=
 
null
)
 
{

            min
.
child 
=
 
null
;

            
Node
 prevx 
=
 
null
,
 nextx 
=
 x
.
sibling
;

            
while
 
(
nextx 
!=
 
null
)
 
{

                x
.
sibling 
=
 prevx
;

                prevx 
=
 x
;

                x 
=
 nextx
;
nextx 
=
 nextx
.
sibling
;

            
}

            x
.
sibling 
=
 prevx
;

            
BinomialMinPQ
< Key >
 H 
=
 
new
 
BinomialMinPQ
< Key >
();

            H
.
head 
=
 x
;

            head 
=
 union
(
H
).
head
;

        
}

        
return
 min
.
key
;

    
}

    

    
/**

     * Merges two Binomial heaps together

     * This operation is destructive

     * Worst case is O(log(n))

     * 
@param
 heap a Binomial Heap to be merged with the current heap

     * 
@throws
 java.lang.IllegalArgumentException if the heap in parameter is null

     * 
@return
 the union of two heaps

     */

    
public
 
BinomialMinPQ
< Key >
 union
(
BinomialMinPQ
< Key >
 heap
)
 
{

        
if
 
(
heap 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“Cannot merge a Binomial Heap with null”
);

        
this
.
head 
=
 merge
(
new
 
Node
(),
 
this
.
head
,
 heap
.
head
).
sibling
;

        
Node
 x 
=
 
this
.
head
;

        
Node
 prevx 
=
 
null
,
 nextx 
=
 x
.
sibling
;

        
while
 
(
nextx 
!=
 
null
)
 
{

            
if
 
(
x
.
order 
<  nextx . order  ||                 ( nextx . sibling  !=   null   &&  nextx . sibling . order  ==  x . order ))   {                 prevx  =  x ;  x  =  nextx ;              }   else   if   ( greater ( nextx . key ,  x . key ))   {                 x . sibling  =  nextx . sibling ;                 link ( nextx ,  x );              }   else   {                  if   ( prevx  ==   null )   {   this . head  =  nextx ;   }                  else   {  prevx . sibling  =  nextx ;   }                 link ( x ,  nextx );                 x  =  nextx ;              }             nextx  =  x . sibling ;          }          return   this ;      }           /*************************************************      * General helper functions      ************************************************/           //Compares two keys      private   boolean  greater ( Key  n ,   Key  m )   {          if   ( n  ==   null )   return   false ;          if   ( m  ==   null )   return   true ;          return  comp . compare ( n ,  m )   >
 
0
;

    
}

    

    
//Assuming root1 holds a greater key than root2, root2 becomes the new root

    
private
 
void
 link
(
Node
 root1
,
 
Node
 root2
)
 
{

        root1
.
sibling 
=
 root2
.
child
;

        root2
.
child 
=
 root1
;

        root2
.
order
++
;

    
}

    

    
//Deletes and return the node containing the minimum key

    
private
 
Node
 eraseMin
()
 
{

        
Node
 min 
=
 head
;

        
Node
 previous 
=
 
null
;

        
Node
 current 
=
 head
;

        
while
 
(
current
.
sibling 
!=
 
null
)
 
{

            
if
 
(
greater
(
min
.
key
,
 current
.
sibling
.
key
))
 
{

                previous 
=
 current
;

                min 
=
 current
.
sibling
;

            
}

            current 
=
 current
.
sibling
;

        
}

        previous
.
sibling 
=
 min
.
sibling
;

        
if
 
(
min 
==
 head
)
 head 
=
 min
.
sibling
;

        
return
 min
;

    
}

    

    
/**************************************************

     * Functions for inserting a key in the heap

     *************************************************/

    

    
//Merges two root lists into one, there can be up to 2 Binomial Trees of same order

        
private
 
Node
 merge
(
Node
 h
,
 
Node
 x
,
 
Node
 y
)
 
{

            
if
 
(

==
 
null
 
&&
 y 
==
 
null
)
 
return
 h
;

            
else
 
if
 
(

==
 
null
)
 h
.
sibling 
=
 merge
(
y
,
 
null
,
 y
.
sibling
);

            
else
 
if
 
(

==
 
null
)
 h
.
sibling 
=
 merge
(
x
,
 x
.
sibling
,
 
null
);

            
else
 
if
 
(
x
.
order 
<  y . order )  h . sibling  =  merge ( x ,  x . sibling ,  y );              else                         h . sibling  =  merge ( y ,  x ,  y . sibling );              return  h ;      }           /******************************************************************      * Iterator      *****************************************************************/           /**      * Gets an Iterator over the keys in the priority queue in ascending order      * The Iterator does not implement the remove() method      * iterator() : Worst case is O(n)      * next() :     Worst case is O(log(n))      * hasNext() :  Worst case is O(1)      *  @return  an Iterator over the keys in the priority queue in ascending order      */      public   Iterator < Key >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Key >
 
{

        
BinomialMinPQ
< Key >
 data
;

        

        
//Constructor clones recursively the elements in the queue

        
//It takes linear time

        
public
 
MyIterator
()
 
{

            data 
=
 
new
 
BinomialMinPQ
< Key >
(
comp
);

            data
.
head 
=
 clone
(
head
,
 
null
);

        
}

        

        
private
 
Node
 clone
(
Node
 x
,
 
Node
 parent
)
 
{

            
if
 
(

==
 
null
)
 
return
 
null
;

            
Node
 node 
=
 
new
 
Node
();

            node
.
key 
=
 x
.
key
;

            node
.
sibling 
=
 clone
(
x
.
sibling
,
 parent
);

            node
.
child 
=
 clone
(
x
.
child
,
 node
);

            
return
 node
;

        
}

        

        
public
 
boolean
 hasNext
()
 
{

            
return
 
!
data
.
isEmpty
();

        
}

        

        
public
 
Key
 next
()
 
{

                        
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
return
 data
.
delMin
();

        
}

        

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

    
}

    

    
/***************************

     * Comparator

     **************************/

    

    
//default Comparator

    
private
 
class
 
MyComparator
 
implements
 
Comparator
< Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

    

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Bipartite.java
edu/princeton/cs/algs4/Bipartite.java
/******************************************************************************

 *  Compilation:  javac Bipartite.java

 *  Execution:    java  Bipartite V E F

 *  Dependencies: Graph.java 

 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt

 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt

 *                https://algs4.cs.princeton.edu/41graph/largeG.txt

 *

 *  Given a graph, find either (i) a bipartition or (ii) an odd-length cycle.

 *  Runs in O(E + V) time.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Bipartite} class represents a data type for 

 *  determining whether an undirected graph is bipartite or whether

 *  it has an odd-length cycle.

 *  A graph is bipartite if and only if it has no odd-length cycle.

 *  The isBipartite operation determines whether the graph is

 *  bipartite. If so, the color operation determines a

 *  bipartition; if not, the oddCycle operation determines a

 *  cycle with an odd number of edges.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in

 *  the worst case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  See {
@link
 BipartiteX} for a nonrecursive version that uses breadth-first

 *  search.

 *  

 *  For additional documentation, see Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Bipartite
 
{

    
private
 
boolean
 isBipartite
;
   
// is the graph bipartite?

    
private
 
boolean
[]
 color
;
       
// color[v] gives vertices on one side of bipartition

    
private
 
boolean
[]
 marked
;
      
// marked[v] = true iff v has been visited in DFS

    
private
 
int
[]
 edgeTo
;
          
// edgeTo[v] = last edge on path to v

    
private
 
Stack
< Integer >
 cycle
;
  
// odd-length cycle

    
/**

     * Determines whether an undirected graph is bipartite and finds either a

     * bipartition or an odd-length cycle.

     *

     * 
@param
  G the graph

     */

    
public
 
Bipartite
(
Graph
 G
)
 
{

        isBipartite 
=
 
true
;

        color  
=
 
new
 
boolean
[
G
.
V
()];

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( ! marked [ v ])   {                 dfs ( G ,  v );              }          }          assert  check ( G );      }      private   void  dfs ( Graph  G ,   int  v )   {           marked [ v ]   =   true ;          for   ( int  w  :  G . adj ( v ))   {              // short circuit if odd-length cycle found              if   ( cycle  !=   null )   return ;              // found uncolored vertex, so recur              if   ( ! marked [ w ])   {                 edgeTo [ w ]   =  v ;                 color [ w ]   =   ! color [ v ];                 dfs ( G ,  w );              }                // if v-w create an odd-length cycle, find it              else   if   ( color [ w ]   ==  color [ v ])   {                 isBipartite  =   false ;                 cycle  =   new   Stack < Integer >
();

                cycle
.
push
(
w
);
  
// don’t need this unless you want to include start vertex twice

                
for
 
(
int
 x 
=
 v
;
 x 
!=
 w
;
 x 
=
 edgeTo
[
x
])
 
{

                    cycle
.
push
(
x
);

                
}

                cycle
.
push
(
w
);

            
}

        
}

    
}

    
/**

     * Returns true if the graph is bipartite.

     *

     * 
@return
 {
@code
 true} if the graph is bipartite; {
@code
 false} otherwise

     */

    
public
 
boolean
 isBipartite
()
 
{

        
return
 isBipartite
;

    
}

 

    
/**

     * Returns the side of the bipartite that vertex {
@code
 v} is on.

     *

     * 
@param
  v the vertex

     * 
@return
 the side of the bipartition that vertex {
@code
 v} is on; two vertices

     *         are in the same side of the bipartition if and only if they have the

     *         same color

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}       *  @throws  UnsupportedOperationException if this method is called when the graph      *         is not bipartite      */      public   boolean  color ( int  v )   {         validateVertex ( v );          if   ( ! isBipartite )              throw   new   UnsupportedOperationException ( "graph is not bipartite" );          return  color [ v ];      }      /**      * Returns an odd-length cycle if the graph is not bipartite, and      * { @code  null} otherwise.      *      *  @return  an odd-length cycle if the graph is not bipartite      *         (and hence has an odd-length cycle), and { @code  null}      *         otherwise      */      public   Iterable < Integer >
 oddCycle
()
 
{

        
return
 cycle
;
 

    
}

    
private
 
boolean
 check
(
Graph
 G
)
 
{

        
// graph is bipartite

        
if
 
(
isBipartite
)
 
{

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {                  for   ( int  w  :  G . adj ( v ))   {                      if   ( color [ v ]   ==  color [ w ])   {                          System . err . printf ( "edge %d-%d with %d and %d in same side of bipartition\n" ,  v ,  w ,  v ,  w );                          return   false ;                      }                  }              }          }          // graph has an odd-length cycle          else   {              // verify cycle              int  first  =   - 1 ,  last  =   - 1 ;              for   ( int  v  :  oddCycle ())   {                  if   ( first  ==   - 1 )  first  =  v ;                 last  =  v ;              }              if   ( first  !=  last )   {                  System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );                  return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 Bipartite} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V1 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 V2 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 E  
=
 
Integer
.
parseInt
(
args
[
2
]);

        
int
 F  
=
 
Integer
.
parseInt
(
args
[
3
]);

        
// create random bipartite graph with V1 vertices on left side,

        
// V2 vertices on right side, and E edges; then add F random edges

        
Graph
 G 
=
 
GraphGenerator
.
bipartite
(
V1
,
 V2
,
 E
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  F ;  i ++ )   {              int  v  =   StdRandom . uniform ( V1  +  V2 );              int  w  =   StdRandom . uniform ( V1  +  V2 );             G . addEdge ( v ,  w );          }          StdOut . println ( G );          Bipartite  b  =   new   Bipartite ( G );          if   ( b . isBipartite ())   {              StdOut . println ( "Graph is bipartite" );              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  StdOut . println ( v  +   ": "   +  b . color ( v ));              }          }          else   {              StdOut . print ( "Graph has an odd-length cycle: " );              for   ( int  x  :  b . oddCycle ())   {                  StdOut . print ( x  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BipartiteMatching.java edu/princeton/cs/algs4/BipartiteMatching.java /******************************************************************************  *  Compilation:  javac BipartiteMatching.java  *  Execution:    java BipartiteMatching V1 V2 E  *  Dependencies: BipartiteX.java  *  *  Find a maximum cardinality matching (and minimum cardinality vertex cover)  *  in a bipartite graph using the alternating path algorithm.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BipartiteMatching} class represents a data type for computing a  *  maximum (cardinality) matching and a

 *  minimum (cardinality) vertex cover in a bipartite graph.

 *  A bipartite graph in a graph whose vertices can be partitioned

 *  into two disjoint sets such that every edge has one endpoint in either set.

 *  A matching in a graph is a subset of its edges with no common

 *  vertices. A maximum matching is a matching with the maximum number

 *  of edges.

 *  A perfect matching is a matching which matches all vertices in the graph.

 *  A vertex cover in a graph is a subset of its vertices such that

 *  every edge is incident to at least one vertex. A minimum vertex cover

 *  is a vertex cover with the minimum number of vertices.

 *  By Konig’s theorem, in any biparite

 *  graph, the maximum number of edges in matching equals the minimum number

 *  of vertices in a vertex cover.

 *  The maximum matching problem in nonbipartite graphs is

 *  also important, but all known algorithms for this more general problem

 *  are substantially more complicated.

 *  

 *  This implementation uses the alternating-path algorithm.

 *  It is equivalent to reducing to the maximum-flow problem and running

 *  the augmenting-path algorithm on the resulting flow network, but it

 *  does so with less overhead.

 *  The constructor takes O((E + VV)

 *  time, where E is the number of edges and V is the

 *  number of vertices in the graph.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  See also {
@link
 HopcroftKarp}, which solves the problem in

 *  O(E sqrt(V)) using the Hopcroft-Karp

 *  algorithm and

 *  BipartiteMatchingToMaxflow,

 *  which solves the problem in O((E + VV)

 *  time via a reduction to maxflow.

 *  

 *  For additional documentation, see

 *  Section 6.5

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BipartiteMatching
 
{

    
private
 
static
 
final
 
int
 UNMATCHED 
=
 

1
;

    
private
 
final
 
int
 V
;
                 
// number of vertices in the graph

    
private
 
BipartiteX
 bipartition
;
      
// the bipartition

    
private
 
int
 cardinality
;
             
// cardinality of current matching

    
private
 
int
[]
 mate
;
                  
// mate[v] =  w if v-w is an edge in current matching

                                         
//         = -1 if v is not in current matching

    
private
 
boolean
[]
 inMinVertexCover
;
  
// inMinVertexCover[v] = true iff v is in min vertex cover

    
private
 
boolean
[]
 marked
;
            
// marked[v] = true iff v is reachable via alternating path

    
private
 
int
[]
 edgeTo
;
                
// edgeTo[v] = last edge on alternating path to v

    
/**

     * Determines a maximum matching (and a minimum vertex cover)

     * in a bipartite graph.

     *

     * 
@param
  G the bipartite graph

     * 
@throws
 IllegalArgumentException if {
@code
 G} is not bipartite

     */

    
public
 
BipartiteMatching
(
Graph
 G
)
 
{

        bipartition 
=
 
new
 
BipartiteX
(
G
);

        
if
 
(
!
bipartition
.
isBipartite
())
 
{

            
throw
 
new
 
IllegalArgumentException
(
“graph is not bipartite”
);

        
}

        
this
.

=
 G
.
V
();

        
// initialize empty matching

        mate 
=
 
new
 
int
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             mate [ v ]   =  UNMATCHED ;          // alternating path algorithm          while   ( hasAugmentingPath ( G ))   {              // find one endpoint t in alternating path              int  t  =   - 1 ;              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  if   ( ! isMatched ( v )   &&  edgeTo [ v ]   !=   - 1 )   {                     t  =  v ;                      break ;                  }              }              // update the matching according to alternating path in edgeTo[] array              for   ( int  v  =  t ;  v  !=   - 1 ;  v  =  edgeTo [ edgeTo [ v ]])   {                  int  w  =  edgeTo [ v ];                 mate [ v ]   =  w ;                 mate [ w ]   =  v ;              }             cardinality ++ ;          }          // find min vertex cover from marked[] array         inMinVertexCover  =   new   boolean [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              if   ( bipartition . color ( v )   &&   ! marked [ v ])  inMinVertexCover [ v ]   =   true ;              if   ( ! bipartition . color ( v )   &&  marked [ v ])  inMinVertexCover [ v ]   =   true ;          }          assert  certifySolution ( G );      }      /*      * is there an augmenting path?      *   - if so, upon termination adj[] contains the level graph;      *   - if not, upon termination marked[] specifies those vertices reachable via an alternating      *     path from one side of the bipartition      *      * an alternating path is a path whose edges belong alternately to the matching and not      * to the matching      *      * an augmenting path is an alternating path that starts and ends at unmatched vertices      *      * this implementation finds a shortest augmenting path (fewest number of edges), though there      * is no particular advantage to do so here      */      private   boolean  hasAugmentingPath ( Graph  G )   {         marked  =   new   boolean [ V ];         edgeTo  =   new   int [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )             edgeTo [ v ]   =   - 1 ;          // breadth-first search (starting from all unmatched vertices on one side of bipartition)          Queue < Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( bipartition . color ( v )   &&   ! isMatched ( v ))   {                 queue . enqueue ( v );                 marked [ v ]   =   true ;              }          }          // run BFS, stopping as soon as an alternating path is found          while   ( ! queue . isEmpty ())   {              int  v  =  queue . dequeue ();              for   ( int  w  :  G . adj ( v ))   {                  // either (1) forward edge not in matching or (2) backward edge in matching                  if   ( isResidualGraphEdge ( v ,  w )   &&   ! marked [ w ])   {                     edgeTo [ w ]   =  v ;                     marked [ w ]   =   true ;                      if   ( ! isMatched ( w ))   return   true ;                     queue . enqueue ( w );                  }              }          }          return   false ;      }      // is the edge v-w a forward edge not in the matching or a reverse edge in the matching?      private   boolean  isResidualGraphEdge ( int  v ,   int  w )   {          if   (( mate [ v ]   !=  w )   &&   bipartition . color ( v ))   return   true ;          if   (( mate [ v ]   ==  w )   &&   ! bipartition . color ( v ))   return   true ;          return   false ;      }      /**      * Returns the vertex to which the specified vertex is matched in      * the maximum matching computed by the algorithm.      *      *  @param   v the vertex      *  @return  the vertex to which vertex { @code  v} is matched in the      *         maximum matching; { @code  -1} if the vertex is not matched      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *      */      public   int  mate ( int  v )   {         validate ( v );          return  mate [ v ];      }      /**      * Returns true if the specified vertex is matched in the maximum matching      * computed by the algorithm.      *      *  @param   v the vertex      *  @return  { @code  true} if vertex { @code  v} is matched in maximum matching;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *      */      public   boolean  isMatched ( int  v )   {         validate ( v );          return  mate [ v ]   !=  UNMATCHED ;      }      /**      * Returns the number of edges in a maximum matching.      *      *  @return  the number of edges in a maximum matching      */      public   int  size ()   {          return  cardinality ;      }      /**      * Returns true if the graph contains a perfect matching.      * That is, the number of edges in a maximum matching is equal to one half      * of the number of vertices in the graph (so that every vertex is matched).      *      *  @return  { @code  true} if the graph contains a perfect matching;      *         { @code  false} otherwise      */      public   boolean  isPerfect ()   {          return  cardinality  *   2   ==  V ;      }      /**      * Returns true if the specified vertex is in the minimum vertex cover      * computed by the algorithm.      *      *  @param   v the vertex      *  @return  { @code  true} if vertex { @code  v} is in the minimum vertex cover;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  inMinVertexCover ( int  v )   {         validate ( v );          return  inMinVertexCover [ v ];      }      private   void  validate ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// check that mate[] and inVertexCover[] define a max matching and min vertex cover, respectively

    
private
 
boolean
 certifySolution
(
Graph
 G
)
 
{

        
// check that mate(v) = w iff mate(w) = v

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( mate ( v )   ==   - 1 )   continue ;              if   ( mate ( mate ( v ))   !=  v )   return   false ;          }          // check that size() is consistent with mate()          int  matchedVertices  =   0 ;          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              if   ( mate ( v )   !=   - 1 )  matchedVertices ++ ;          }          if   ( 2 * size ()   !=  matchedVertices )   return   false ;          // check that size() is consistent with minVertexCover()          int  sizeOfMinVertexCover  =   0 ;          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              if   ( inMinVertexCover ( v ))  sizeOfMinVertexCover ++ ;          if   ( size ()   !=  sizeOfMinVertexCover )   return   false ;          // check that mate() uses each vertex at most once          boolean []  isMatched  =   new   boolean [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              int  w  =  mate [ v ];              if   ( w  ==   - 1 )   continue ;              if   ( v  ==  w )   return   false ;              if   ( v  >=
 w
)
 
continue
;

            
if
 
(
isMatched
[
v
]
 
||
 isMatched
[
w
])
 
return
 
false
;

            isMatched
[
v
]
 
=
 
true
;

            isMatched
[
w
]
 
=
 
true
;

        
}

        
// check that mate() uses only edges that appear in the graph

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( mate ( v )   ==   - 1 )   continue ;              boolean  isEdge  =   false ;              for   ( int  w  :  G . adj ( v ))   {                  if   ( mate ( v )   ==  w )  isEdge  =   true ;              }              if   ( ! isEdge )   return   false ;          }          // check that inMinVertexCover() is a vertex cover          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              for   ( int  w  :  G . adj ( v ))                  if   ( ! inMinVertexCover ( v )   &&   ! inMinVertexCover ( w ))   return   false ;          return   true ;      }      /**      * Unit tests the { @code  HopcroftKarp} data type.      * Takes three command-line arguments { @code  V1}, { @code  V2}, and { @code  E};      * creates a random bipartite graph with { @code  V1} + { @code  V2} vertices      * and { @code  E} edges; computes a maximum matching and minimum vertex cover;      * and prints the results.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  V1  =   Integer . parseInt ( args [ 0 ]);          int  V2  =   Integer . parseInt ( args [ 1 ]);          int  E   =   Integer . parseInt ( args [ 2 ]);          Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );          if   ( G . V ()   <   1000 )   StdOut . println ( G );          BipartiteMatching  matching  =   new   BipartiteMatching ( G );                   // print maximum matching          StdOut . printf ( "Number of edges in max matching        = %d\n" ,  matching . size ());          StdOut . printf ( "Number of vertices in min vertex cover = %d\n" ,  matching . size ());          StdOut . printf ( "Graph has a perfect matching           = %b\n" ,  matching . isPerfect ());          StdOut . println ();          if   ( G . V ()   >=
 
1000
)
 
return
;

        
StdOut
.
print
(
“Max matching: ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              int  w  =  matching . mate ( v );              if   ( matching . isMatched ( v )   &&  v  <  w )    // print each edge only once                  StdOut . print ( v  +   "-"   +  w  +   " " );          }          StdOut . println ();          // print minimum vertex cover          StdOut . print ( "Min vertex cover: " );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              if   ( matching . inMinVertexCover ( v ))                  StdOut . print ( v  +   " " );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BipartiteX.java edu/princeton/cs/algs4/BipartiteX.java /******************************************************************************  *  Compilation:  javac BipartiteX.java  *  Execution:    java  Bipartite V E F  *  Dependencies: Graph.java   *  *  Given a graph, find either (i) a bipartition or (ii) an odd-length cycle.  *  Runs in O(E + V) time.  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BipartiteX} class represents a data type for   *  determining whether an undirected graph is bipartite or whether

 *  it has an odd-length cycle.

 *  A graph is bipartite if and only if it has no odd-length cycle.

 *  The isBipartite operation determines whether the graph is

 *  bipartite. If so, the color operation determines a

 *  bipartition; if not, the oddCycle operation determines a

 *  cycle with an odd number of edges.

 *  

 *  This implementation uses breadth-first search and is nonrecursive.

 *  The constructor takes Θ(V + E) time in

 *  in the worst case, where V is the number of vertices

 *  and E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  See {
@link
 Bipartite} for a recursive version that uses depth-first search.

 *  

 *  For additional documentation,

 *  see Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BipartiteX
 
{

    
private
 
static
 
final
 
boolean
 WHITE 
=
 
false
;

    
private
 
static
 
final
 
boolean
 BLACK 
=
 
true
;

    
private
 
boolean
 isBipartite
;
   
// is the graph bipartite?

    
private
 
boolean
[]
 color
;
       
// color[v] gives vertices on one side of bipartition

    
private
 
boolean
[]
 marked
;
      
// marked[v] = true iff v has been visited in DFS

    
private
 
int
[]
 edgeTo
;
          
// edgeTo[v] = last edge on path to v

    
private
 
Queue
< Integer >
 cycle
;
  
// odd-length cycle

    
/**

     * Determines whether an undirected graph is bipartite and finds either a

     * bipartition or an odd-length cycle.

     *

     * 
@param
  G the graph

     */

    
public
 
BipartiteX
(
Graph
 G
)
 
{

        isBipartite 
=
 
true
;

        color  
=
 
new
 
boolean
[
G
.
V
()];

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ()   &&  isBipartite ;  v ++ )   {              if   ( ! marked [ v ])   {                 bfs ( G ,  v );              }          }          assert  check ( G );      }      private   void  bfs ( Graph  G ,   int  s )   {            Queue < Integer >
 q 
=
 
new
 
Queue
< Integer >
();

        color
[
s
]
 
=
 WHITE
;

        marked
[
s
]
 
=
 
true
;

        q
.
enqueue
(
s
);

        
while
 
(
!
q
.
isEmpty
())
 
{

            
int
 v 
=
 q
.
dequeue
();

            
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

                
if
 
(
!
marked
[
w
])
 
{

                    marked
[
w
]
 
=
 
true
;

                    edgeTo
[
w
]
 
=
 v
;

                    color
[
w
]
 
=
 
!
color
[
v
];

                    q
.
enqueue
(
w
);

                
}

                
else
 
if
 
(
color
[
w
]
 
==
 color
[
v
])
 
{

                    isBipartite 
=
 
false
;

                    
// to form odd cycle, consider s-v path and s-w path

                    
// and let x be closest node to v and w common to two paths

                    
// then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle

                    
// Note: distTo[v] == distTo[w];

                    cycle 
=
 
new
 
Queue
< Integer >
();

                    
Stack
< Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

                    
int
 x 
=
 v
,
 y 
=
 w
;

                    
while
 
(

!=
 y
)
 
{

                        stack
.
push
(
x
);

                        cycle
.
enqueue
(
y
);

                        x 
=
 edgeTo
[
x
];

                        y 
=
 edgeTo
[
y
];

                    
}

                    stack
.
push
(
x
);

                    
while
 
(
!
stack
.
isEmpty
())

                        cycle
.
enqueue
(
stack
.
pop
());

                    cycle
.
enqueue
(
w
);

                    
return
;

                
}

            
}

        
}

    
}

    
/**

     * Returns true if the graph is bipartite.

     *

     * 
@return
 {
@code
 true} if the graph is bipartite; {
@code
 false} otherwise

     */

    
public
 
boolean
 isBipartite
()
 
{

        
return
 isBipartite
;

    
}

 

    
/**

     * Returns the side of the bipartite that vertex {
@code
 v} is on.

     *

     * 
@param
  v the vertex

     * 
@return
 the side of the bipartition that vertex {
@code
 v} is on; two vertices

     *         are in the same side of the bipartition if and only if they have the

     *         same color

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}       *  @throws  UnsupportedOperationException if this method is called when the graph      *         is not bipartite      */      public   boolean  color ( int  v )   {         validateVertex ( v );          if   ( ! isBipartite )              throw   new   UnsupportedOperationException ( "Graph is not bipartite" );          return  color [ v ];      }      /**      * Returns an odd-length cycle if the graph is not bipartite, and      * { @code  null} otherwise.      *      *  @return  an odd-length cycle if the graph is not bipartite      *         (and hence has an odd-length cycle), and { @code  null}      *         otherwise      */      public   Iterable < Integer >
 oddCycle
()
 
{

        
return
 cycle
;
 

    
}

    
private
 
boolean
 check
(
Graph
 G
)
 
{

        
// graph is bipartite

        
if
 
(
isBipartite
)
 
{

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {                  for   ( int  w  :  G . adj ( v ))   {                      if   ( color [ v ]   ==  color [ w ])   {                          System . err . printf ( "edge %d-%d with %d and %d in same side of bipartition\n" ,  v ,  w ,  v ,  w );                          return   false ;                      }                  }              }          }          // graph has an odd-length cycle          else   {              // verify cycle              int  first  =   - 1 ,  last  =   - 1 ;              for   ( int  v  :  oddCycle ())   {                  if   ( first  ==   - 1 )  first  =  v ;                 last  =  v ;              }              if   ( first  !=  last )   {                  System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );                  return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 BipartiteX} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V1 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 V2 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 E  
=
 
Integer
.
parseInt
(
args
[
2
]);

        
int
 F  
=
 
Integer
.
parseInt
(
args
[
3
]);

        
// create random bipartite graph with V1 vertices on left side,

        
// V2 vertices on right side, and E edges; then add F random edges

        
Graph
 G 
=
 
GraphGenerator
.
bipartite
(
V1
,
 V2
,
 E
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  F ;  i ++ )   {              int  v  =   StdRandom . uniform ( V1  +  V2 );              int  w  =   StdRandom . uniform ( V1  +  V2 );             G . addEdge ( v ,  w );          }          StdOut . println ( G );          BipartiteX  b  =   new   BipartiteX ( G );          if   ( b . isBipartite ())   {              StdOut . println ( "Graph is bipartite" );              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  StdOut . println ( v  +   ": "   +  b . color ( v ));              }          }          else   {              StdOut . print ( "Graph has an odd-length cycle: " );              for   ( int  x  :  b . oddCycle ())   {                  StdOut . print ( x  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BlackFilter.java edu/princeton/cs/algs4/BlackFilter.java /******************************************************************************  *  Compilation:  javac BlackFilter.java  *  Execution:    java BlackFilter blacklist.txt < input.txt  *  Dependencies: SET In.java StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt  *                https://algs4.cs.princeton.edu/35applications/list.txt  *  *  Read in a blacklist of words from a file. Then read in a list of  *  words from standard input and print out all those words that  *  are not in the first file.  *   *  % more tinyTale.txt   *  it was the best of times it was the worst of times   *  it was the age of wisdom it was the age of foolishness   *  it was the epoch of belief it was the epoch of incredulity   *  it was the season of light it was the season of darkness   *  it was the spring of hope it was the winter of despair  *  *  % more list.txt   *  was it the of   *   *  % java BlackFilter list.txt < tinyTale.txt   *  best times worst times   *  age wisdom age foolishness   *  epoch belief epoch incredulity   *  season light season darkness   *  spring hope winter despair   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BlackFilter} class provides a client for reading in a blacklist

 *  of words from a file; then, reading in a sequence of words from standard input, 

 *  printing out each word that does not appear in the file. 

 *  It is useful as a test client for various symbol table implementations.   

 *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BlackFilter
 
{
  

    
// Do not instantiate.

    
private
 
BlackFilter
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        SET
< String >
 set 
=
 
new
 SET
< String >
();

        
// read in strings and add to set

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
while
 
(
!
in
.
isEmpty
())
 
{

            
String
 word 
=
 in
.
readString
();

            set
.
add
(
word
);

        
}

        
// read in string from standard input, printing out all exceptions

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 word 
=
 
StdIn
.
readString
();

            
if
 
(
!
set
.
contains
(
word
))

                
StdOut
.
println
(
word
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BoruvkaMST.java
edu/princeton/cs/algs4/BoruvkaMST.java
/******************************************************************************

 *  Compilation:  javac BoruvkaMST.java

 *  Execution:    java BoruvkaMST filename.txt

 *  Dependencies: EdgeWeightedGraph.java Edge.java Bag.java

 *                UF.java In.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt

 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt

 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt

 *

 *  Compute a minimum spanning forest using Boruvka’s algorithm.

 *

 *  % java BoruvkaMST tinyEWG.txt 

 *  0-2 0.26000

 *  6-2 0.40000

 *  5-7 0.28000

 *  4-5 0.35000

 *  2-3 0.17000

 *  1-7 0.19000

 *  0-7 0.16000

 *  1.81000

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 BoruvkaMST} class represents a data type for computing a

 *  minimum spanning tree in an edge-weighted graph.

 *  The edge weights can be positive, zero, or negative and need not

 *  be distinct. If the graph is not connected, it computes a minimum

 *  spanning forest, which is the union of minimum spanning trees

 *  in each connected component. The {
@code
 weight()} method returns the 

 *  weight of a minimum spanning tree and the {
@code
 edges()} method

 *  returns its edges.

 *  

 *  This implementation uses Boruvka’s algorithm and the union-find

 *  data type.

 *  The constructor takes Θ(E log V) time in

 *  the worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted graph).

 *  

 *  For additional documentation,

 *  see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For alternate implementations, see {
@link
 LazyPrimMST}, {
@link
 PrimMST},

 *  and {
@link
 KruskalMST}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BoruvkaMST
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-12
;

    
private
 
Bag
< Edge >
 mst 
=
 
new
 
Bag
< Edge >
();
    
// edges in MST

    
private
 
double
 weight
;
                      
// weight of MST

    
/**

     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.

     * 
@param
 G the edge-weighted graph

     */

    
public
 
BoruvkaMST
(
EdgeWeightedGraph
 G
)
 
{

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
// repeat at most log V times or until we have V-1 edges

        
for
 
(
int
 t 
=
 
1
;
 t 
<  G . V ()   &&  mst . size ()   <  G . V ()   -   1 ;  t  =  t  +  t )   {              // foreach tree in forest, find closest edge              // if edge weights are equal, ties are broken in favor of first edge in G.edges()              Edge []  closest  =   new   Edge [ G . V ()];              for   ( Edge  e  :  G . edges ())   {                  int  v  =  e . either (),  w  =  e . other ( v );                  int  i  =  uf . find ( v ),  j  =  uf . find ( w );                  if   ( i  ==  j )   continue ;     // same tree                  if   ( closest [ i ]   ==   null   ||  less ( e ,  closest [ i ]))  closest [ i ]   =  e ;                  if   ( closest [ j ]   ==   null   ||  less ( e ,  closest [ j ]))  closest [ j ]   =  e ;              }              // add newly discovered edges to MST              for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {                  Edge  e  =  closest [ i ];                  if   ( e  !=   null )   {                      int  v  =  e . either (),  w  =  e . other ( v );                      // don't add the same edge twice                      if   ( uf . find ( v )   !=  uf . find ( w ))   {                         mst . add ( e );                         weight  +=  e . weight ();                         uf . union ( v ,  w );                      }                  }              }          }          // check optimality conditions          assert  check ( G );      }      /**      * Returns the edges in a minimum spanning tree (or forest).      *  @return  the edges in a minimum spanning tree (or forest) as      *    an iterable of edges      */      public   Iterable < Edge >
 edges
()
 
{

        
return
 mst
;

    
}

    
/**

     * Returns the sum of the edge weights in a minimum spanning tree (or forest).

     * 
@return
 the sum of the edge weights in a minimum spanning tree (or forest)

     */

    
public
 
double
 weight
()
 
{

        
return
 weight
;

    
}

    
// is the weight of edge e strictly less than that of edge f?

    
private
 
static
 
boolean
 less
(
Edge
 e
,
 
Edge
 f
)
 
{

        
return
 e
.
compareTo
(
f
)
 
<   0 ;      }      // check optimality conditions (takes time proportional to E V lg* V)      private   boolean  check ( EdgeWeightedGraph  G )   {          // check weight          double  totalWeight  =   0.0 ;          for   ( Edge  e  :  edges ())   {             totalWeight  +=  e . weight ();          }          if   ( Math . abs ( totalWeight  -  weight ())   >
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
printf
(
“Weight of edges does not equal weight(): %f vs. %f\n”
,
 totalWeight
,
 weight
());

            
return
 
false
;

        
}

        
// check that it is acyclic

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
==
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a forest”
);

                
return
 
false
;

            
}

            uf
.
union
(
v
,
 w
);

        
}

        
// check that it is a spanning forest

        
for
 
(
Edge
 e 
:
 G
.
edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
!=
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a spanning forest”
);

                
return
 
false
;

            
}

        
}

        
// check that it is a minimal spanning forest (cut optimality conditions)

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
// all edges in MST except e

            uf 
=
 
new
 UF
(
G
.
V
());

            
for
 
(
Edge
 f 
:
 mst
)
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(

!=
 e
)
 uf
.
union
(
x
,
 y
);

            
}

            
// check that e is min weight edge in crossing cut

            
for
 
(
Edge
 f 
:
 G
.
edges
())
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(
uf
.
find
(
x
)
 
!=
 uf
.
find
(
y
))
 
{

                    
if
 
(
f
.
weight
()
 
<  e . weight ())   {                          System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );                          return   false ;                      }                  }              }          }          return   true ;      }      /**      * Unit tests the { @code  BoruvkaMST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );          BoruvkaMST  mst  =   new   BoruvkaMST ( G );          for   ( Edge  e  :  mst . edges ())   {              StdOut . println ( e );          }          StdOut . printf ( "%.5f\n" ,  mst . weight ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BoyerMoore.java edu/princeton/cs/algs4/BoyerMoore.java /******************************************************************************  *  Compilation:  javac BoyerMoore.java  *  Execution:    java BoyerMoore pattern text  *  Dependencies: StdOut.java  *  *  Reads in two strings, the pattern and the input text, and  *  searches for the pattern in the input text using the  *  bad-character rule part of the Boyer-Moore algorithm.  *  (does not implement the strong good suffix rule)  *  *  % java BoyerMoore abracadabra abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:               abracadabra  *  *  % java BoyerMoore rab abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:         rab  *  *  % java BoyerMoore bcara abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:                                   bcara  *  *  % java BoyerMoore rabrabracad abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad  *  pattern:                        rabrabracad  *  *  % java BoyerMoore abacad abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad  *  pattern: abacad  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  BoyerMoore} class finds the first occurrence of a pattern string  *  in a text string.  *  

 *  This implementation uses the Boyer-Moore algorithm (with the bad-character

 *  rule, but not the strong good suffix rule).

 *  

 *  For additional documentation,

 *  see Section 5.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
BoyerMoore
 
{

    
private
 
final
 
int
 R
;
     
// the radix

    
private
 
int
[]
 right
;
     
// the bad-character skip array

    
private
 
char
[]
 pattern
;
  
// store the pattern as a character array

    
private
 
String
 pat
;
      
// or as a string

    
/**

     * Preprocesses the pattern string.

     *

     * 
@param
 pat the pattern string

     */

    
public
 
BoyerMoore
(
String
 pat
)
 
{

        
this
.

=
 
256
;

        
this
.
pat 
=
 pat
;

        
// position of rightmost occurrence of c in the pattern

        right 
=
 
new
 
int
[
R
];

        
for
 
(
int
 c 
=
 
0
;
 c 
<  R ;  c ++ )             right [ c ]   =   - 1 ;          for   ( int  j  =   0 ;  j  <  pat . length ();  j ++ )             right [ pat . charAt ( j )]   =  j ;      }      /**      * Preprocesses the pattern string.      *      *  @param  pattern the pattern string      *  @param  R the alphabet size      */      public   BoyerMoore ( char []  pattern ,   int  R )   {          this . R  =  R ;          this . pattern  =   new   char [ pattern . length ];          for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )              this . pattern [ j ]   =  pattern [ j ];          // position of rightmost occurrence of c in the pattern         right  =   new   int [ R ];          for   ( int  c  =   0 ;  c  <  R ;  c ++ )             right [ c ]   =   - 1 ;          for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )             right [ pattern [ j ]]   =  j ;      }      /**      * Returns the index of the first occurrrence of the pattern string      * in the text string.      *      *  @param   txt the text string      *  @return  the index of the first occurrence of the pattern string      *         in the text string; n if no such match      */      public   int  search ( String  txt )   {          int  m  =  pat . length ();          int  n  =  txt . length ();          int  skip ;          for   ( int  i  =   0 ;  i  <=  n  -  m ;  i  +=  skip )   {             skip  =   0 ;              for   ( int  j  =  m - 1 ;  j  >=
 
0
;
 j

)
 
{

                
if
 
(
pat
.
charAt
(
j
)
 
!=
 txt
.
charAt
(
i
+
j
))
 
{

                    skip 
=
 
Math
.
max
(
1
,
 j 

 right
[
txt
.
charAt
(
i
+
j
)]);

                    
break
;

                
}

            
}

            
if
 
(
skip 
==
 
0
)
 
return
 i
;
    
// found

        
}

        
return
 n
;
                       
// not found

    
}

    
/**

     * Returns the index of the first occurrrence of the pattern string

     * in the text string.

     *

     * 
@param
  text the text string

     * 
@return
 the index of the first occurrence of the pattern string

     *         in the text string; n if no such match

     */

    
public
 
int
 search
(
char
[]
 text
)
 
{

        
int
 m 
=
 pattern
.
length
;

        
int
 n 
=
 text
.
length
;

        
int
 skip
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<=  n  -  m ;  i  +=  skip )   {             skip  =   0 ;              for   ( int  j  =  m - 1 ;  j  >=
 
0
;
 j

)
 
{

                
if
 
(
pattern
[
j
]
 
!=
 text
[
i
+
j
])
 
{

                    skip 
=
 
Math
.
max
(
1
,
 j 

 right
[
text
[
i
+
j
]]);

                    
break
;

                
}

            
}

            
if
 
(
skip 
==
 
0
)
 
return
 i
;
    
// found

        
}

        
return
 n
;
                       
// not found

    
}

    
/**

     * Takes a pattern string and an input string as command-line arguments;

     * searches for the pattern string in the text string; and prints

     * the first occurrence of the pattern string in the text string.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 pat 
=
 args
[
0
];

        
String
 txt 
=
 args
[
1
];

        
char
[]
 pattern 
=
 pat
.
toCharArray
();

        
char
[]
 text    
=
 txt
.
toCharArray
();

        
BoyerMoore
 boyermoore1 
=
 
new
 
BoyerMoore
(
pat
);

        
BoyerMoore
 boyermoore2 
=
 
new
 
BoyerMoore
(
pattern
,
 
256
);

        
int
 offset1 
=
 boyermoore1
.
search
(
txt
);

        
int
 offset2 
=
 boyermoore2
.
search
(
text
);

        
// print results

        
StdOut
.
println
(
“text:    ”
 
+
 txt
);

        
StdOut
.
print
(
“pattern: ”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  offset1 ;  i ++ )              StdOut . print ( " " );          StdOut . println ( pat );          StdOut . print ( "pattern: " );          for   ( int  i  =   0 ;  i  <  offset2 ;  i ++ )              StdOut . print ( " " );          StdOut . println ( pat );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BreadthFirstDirectedPaths.java edu/princeton/cs/algs4/BreadthFirstDirectedPaths.java /******************************************************************************  *  Compilation:  javac BreadthFirstDirectedPaths.java  *  Execution:    java BreadthFirstDirectedPaths digraph.txt s  *  Dependencies: Digraph.java Queue.java Stack.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt  *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt  *  *  Run breadth-first search on a digraph.  *  Runs in O(E + V) time.  *  *  % java BreadthFirstDirectedPaths tinyDG.txt 3  *  3 to 0 (2):  3->2->0

 *  3 to 1 (3):  3->2->0->1

 *  3 to 2 (1):  3->2

 *  3 to 3 (0):  3

 *  3 to 4 (2):  3->5->4

 *  3 to 5 (1):  3->5

 *  3 to 6 (-):  not connected

 *  3 to 7 (-):  not connected

 *  3 to 8 (-):  not connected

 *  3 to 9 (-):  not connected

 *  3 to 10 (-):  not connected

 *  3 to 11 (-):  not connected

 *  3 to 12 (-):  not connected

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 BreadthDirectedFirstPaths} class represents a data type for

 *  finding shortest paths (number of edges) from a source vertex s

 *  (or set of source vertices) to every other vertex in the digraph.

 *  

 *  This implementation uses breadth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and E is

 *  the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  For additional documentation, 

 *  see Section 4.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BreadthFirstDirectedPaths
 
{

    
private
 
static
 
final
 
int
 INFINITY 
=
 
Integer
.
MAX_VALUE
;

    
private
 
boolean
[]
 marked
;
  
// marked[v] = is there an s->v path?

    
private
 
int
[]
 edgeTo
;
      
// edgeTo[v] = last edge on shortest s->v path

    
private
 
int
[]
 distTo
;
      
// distTo[v] = length of shortest s->v path

    
/**

     * Computes the shortest path from {
@code
 s} and every other vertex in graph {
@code
 G}.

     * 
@param
 G the digraph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   BreadthFirstDirectedPaths ( Digraph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         distTo  =   new   int [ G . V ()];         edgeTo  =   new   int [ G . V ()];          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =  INFINITY ;         validateVertex ( s );         bfs ( G ,  s );      }      /**      * Computes the shortest path from any one of the source vertices in { @code  sources}      * to every other vertex in graph { @code  G}.      *  @param  G the digraph      *  @param  sources the source vertices      *  @throws  IllegalArgumentException unless each vertex { @code  v} in      *         { @code  sources} satisfies { @code  0 <= v < V}      */      public   BreadthFirstDirectedPaths ( Digraph  G ,   Iterable < Integer >
 sources
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        distTo 
=
 
new
 
int
[
G
.
V
()];

        edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             distTo [ v ]   =  INFINITY ;         validateVertices ( sources );         bfs ( G ,  sources );      }      // BFS from single source      private   void  bfs ( Digraph  G ,   int  s )   {          Queue < Integer >
 q 
=
 
new
 
Queue
< Integer >
();

        marked
[
s
]
 
=
 
true
;

        distTo
[
s
]
 
=
 
0
;

        q
.
enqueue
(
s
);

        
while
 
(
!
q
.
isEmpty
())
 
{

            
int
 v 
=
 q
.
dequeue
();

            
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

                
if
 
(
!
marked
[
w
])
 
{

                    edgeTo
[
w
]
 
=
 v
;

                    distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 
1
;

                    marked
[
w
]
 
=
 
true
;

                    q
.
enqueue
(
w
);

                
}

            
}

        
}

    
}

    
// BFS from multiple sources

    
private
 
void
 bfs
(
Digraph
 G
,
 
Iterable
< Integer >
 sources
)
 
{

        
Queue
< Integer >
 q 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 s 
:
 sources
)
 
{

            marked
[
s
]
 
=
 
true
;

            distTo
[
s
]
 
=
 
0
;

            q
.
enqueue
(
s
);

        
}

        
while
 
(
!
q
.
isEmpty
())
 
{

            
int
 v 
=
 q
.
dequeue
();

            
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

                
if
 
(
!
marked
[
w
])
 
{

                    edgeTo
[
w
]
 
=
 v
;

                    distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 
1
;

                    marked
[
w
]
 
=
 
true
;

                    q
.
enqueue
(
w
);

                
}

            
}

        
}

    
}

    
/**

     * Is there a directed path from the source {
@code
 s} (or sources) to vertex {
@code
 v}?

     * 
@param
 v the vertex

     * 
@return
 {
@code
 true} if there is a directed path, {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      /**      * Returns the number of edges in a shortest path from the source { @code  s}      * (or sources) to vertex { @code  v}?      *  @param  v the vertex      *  @return  the number of edges in a shortest path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Returns a shortest path from { @code  s} (or sources) to { @code  v}, or      * { @code  null} if no such path.      *  @param  v the vertex      *  @return  the sequence of vertices on a shortest path, as an Iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< Integer >
 path 
=
 
new
 
Stack
< Integer >
();

        
int
 x
;

        
for
 
(

=
 v
;
 distTo
[
x
]
 
!=
 
0
;
 x 
=
 edgeTo
[
x
])

            path
.
push
(
x
);

        path
.
push
(
x
);

        
return
 path
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertices ( Iterable < Integer >
 vertices
)
 
{

        
if
 
(
vertices 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
}

        
int
 V 
=
 marked
.
length
;

        
for
 
(
int
 v 
:
 vertices
)
 
{

            
if
 
(

<   0   ||  v  >=
 V
)
 
{

                
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

            
}

        
}

    
}

    
/**

     * Unit tests the {
@code
 BreadthFirstDirectedPaths} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
// StdOut.println(G);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
BreadthFirstDirectedPaths
 bfs 
=
 
new
 
BreadthFirstDirectedPaths
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( bfs . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d (%d):  " ,  s ,  v ,  bfs . distTo ( v ));                  for   ( int  x  :  bfs . pathTo ( v ))   {                      if   ( x  ==  s )   StdOut . print ( x );                      else          StdOut . print ( "->”
 
+
 x
);

                
}

                
StdOut
.
println
();

            
}

            
else
 
{

                
StdOut
.
printf
(
“%d to %d (-):  not connected\n”
,
 s
,
 v
);

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BreadthFirstPaths.java
edu/princeton/cs/algs4/BreadthFirstPaths.java
/******************************************************************************

 *  Compilation:  javac BreadthFirstPaths.java

 *  Execution:    java BreadthFirstPaths G s

 *  Dependencies: Graph.java Queue.java Stack.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt

 *                https://algs4.cs.princeton.edu/41graph/tinyG.txt

 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt

 *                https://algs4.cs.princeton.edu/41graph/largeG.txt

 *

 *  Run breadth first search on an undirected graph.

 *  Runs in O(E + V) time.

 *

 *  %  java Graph tinyCG.txt

 *  6 8

 *  0: 2 1 5 

 *  1: 0 2 

 *  2: 0 1 3 4 

 *  3: 5 4 2 

 *  4: 3 2 

 *  5: 3 0 

 *

 *  %  java BreadthFirstPaths tinyCG.txt 0

 *  0 to 0 (0):  0

 *  0 to 1 (1):  0-1

 *  0 to 2 (1):  0-2

 *  0 to 3 (2):  0-2-3

 *  0 to 4 (2):  0-2-4

 *  0 to 5 (1):  0-5

 *

 *  %  java BreadthFirstPaths largeG.txt 0

 *  0 to 0 (0):  0

 *  0 to 1 (418):  0-932942-474885-82707-879889-971961-…

 *  0 to 2 (323):  0-460790-53370-594358-780059-287921-…

 *  0 to 3 (168):  0-713461-75230-953125-568284-350405-…

 *  0 to 4 (144):  0-460790-53370-310931-440226-380102-…

 *  0 to 5 (566):  0-932942-474885-82707-879889-971961-…

 *  0 to 6 (349):  0-932942-474885-82707-879889-971961-…

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 BreadthFirstPaths} class represents a data type for finding

 *  shortest paths (number of edges) from a source vertex s

 *  (or a set of source vertices)

 *  to every other vertex in an undirected graph.

 *  

 *  This implementation uses breadth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  For additional documentation,

 *  see Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
BreadthFirstPaths
 
{

    
private
 
static
 
final
 
int
 INFINITY 
=
 
Integer
.
MAX_VALUE
;

    
private
 
boolean
[]
 marked
;
  
// marked[v] = is there an s-v path

    
private
 
int
[]
 edgeTo
;
      
// edgeTo[v] = previous edge on shortest s-v path

    
private
 
int
[]
 distTo
;
      
// distTo[v] = number of edges shortest s-v path

    
/**

     * Computes the shortest path between the source vertex {
@code
 s}

     * and every other vertex in the graph {
@code
 G}.

     * 
@param
 G the graph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   BreadthFirstPaths ( Graph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         distTo  =   new   int [ G . V ()];         edgeTo  =   new   int [ G . V ()];         validateVertex ( s );         bfs ( G ,  s );          assert  check ( G ,  s );      }      /**      * Computes the shortest path between any one of the source vertices in { @code  sources}      * and every other vertex in graph { @code  G}.      *  @param  G the graph      *  @param  sources the source vertices      *  @throws  IllegalArgumentException unless { @code  0 <= s < V} for each vertex      *         { @code  s} in { @code  sources}      */      public   BreadthFirstPaths ( Graph  G ,   Iterable < Integer >
 sources
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        distTo 
=
 
new
 
int
[
G
.
V
()];

        edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             distTo [ v ]   =  INFINITY ;         validateVertices ( sources );         bfs ( G ,  sources );      }      // breadth-first search from a single source      private   void  bfs ( Graph  G ,   int  s )   {          Queue < Integer >
 q 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             distTo [ v ]   =  INFINITY ;         distTo [ s ]   =   0 ;         marked [ s ]   =   true ;         q . enqueue ( s );          while   ( ! q . isEmpty ())   {              int  v  =  q . dequeue ();              for   ( int  w  :  G . adj ( v ))   {                  if   ( ! marked [ w ])   {                     edgeTo [ w ]   =  v ;                     distTo [ w ]   =  distTo [ v ]   +   1 ;                     marked [ w ]   =   true ;                     q . enqueue ( w );                  }              }          }      }      // breadth-first search from multiple sources      private   void  bfs ( Graph  G ,   Iterable < Integer >
 sources
)
 
{

        
Queue
< Integer >
 q 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 s 
:
 sources
)
 
{

            marked
[
s
]
 
=
 
true
;

            distTo
[
s
]
 
=
 
0
;

            q
.
enqueue
(
s
);

        
}

        
while
 
(
!
q
.
isEmpty
())
 
{

            
int
 v 
=
 q
.
dequeue
();

            
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

                
if
 
(
!
marked
[
w
])
 
{

                    edgeTo
[
w
]
 
=
 v
;

                    distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 
1
;

                    marked
[
w
]
 
=
 
true
;

                    q
.
enqueue
(
w
);

                
}

            
}

        
}

    
}

    
/**

     * Is there a path between the source vertex {
@code
 s} (or sources) and vertex {
@code
 v}?

     * 
@param
 v the vertex

     * 
@return
 {
@code
 true} if there is a path, and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      /**      * Returns the number of edges in a shortest path between the source vertex { @code  s}      * (or sources) and vertex { @code  v}?      *  @param  v the vertex      *  @return  the number of edges in a shortest path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Returns a shortest path between the source vertex { @code  s} (or sources)      * and { @code  v}, or { @code  null} if no such path.      *  @param   v the vertex      *  @return  the sequence of vertices on a shortest path, as an Iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< Integer >
 path 
=
 
new
 
Stack
< Integer >
();

        
int
 x
;

        
for
 
(

=
 v
;
 distTo
[
x
]
 
!=
 
0
;
 x 
=
 edgeTo
[
x
])

            path
.
push
(
x
);

        path
.
push
(
x
);

        
return
 path
;

    
}

    
// check optimality conditions for single source

    
private
 
boolean
 check
(
Graph
 G
,
 
int
 s
)
 
{

        
// check that the distance of s = 0

        
if
 
(
distTo
[
s
]
 
!=
 
0
)
 
{

            
StdOut
.
println
(
“distance of source ”
 
+
 s 
+
 
” to itself = ”
 
+
 distTo
[
s
]);

            
return
 
false
;

        
}

        
// check that for each edge v-w dist[w] <= dist[v] + 1          // provided v is reachable from s          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  :  G . adj ( v ))   {                  if   ( hasPathTo ( v )   !=  hasPathTo ( w ))   {                      StdOut . println ( "edge "   +  v  +   "-"   +  w );                      StdOut . println ( "hasPathTo("   +  v  +   ") = "   +  hasPathTo ( v ));                      StdOut . println ( "hasPathTo("   +  w  +   ") = "   +  hasPathTo ( w ));                      return   false ;                  }                  if   ( hasPathTo ( v )   &&   ( distTo [ w ]   >
 distTo
[
v
]
 
+
 
1
))
 
{

                    
StdOut
.
println
(
“edge ”
 
+
 v 
+
 
“-”
 
+
 w
);

                    
StdOut
.
println
(
“distTo[”
 
+
 v 
+
 
“] = ”
 
+
 distTo
[
v
]);

                    
StdOut
.
println
(
“distTo[”
 
+
 w 
+
 
“] = ”
 
+
 distTo
[
w
]);

                    
return
 
false
;

                
}

            
}

        
}

        
// check that v = edgeTo[w] satisfies distTo[w] = distTo[v] + 1

        
// provided v is reachable from s

        
for
 
(
int
 w 
=
 
0
;
 w 
<  G . V ();  w ++ )   {              if   ( ! hasPathTo ( w )   ||  w  ==  s )   continue ;              int  v  =  edgeTo [ w ];              if   ( distTo [ w ]   !=  distTo [ v ]   +   1 )   {                  StdOut . println ( "shortest path edge "   +  v  +   "-"   +  w );                  StdOut . println ( "distTo["   +  v  +   "] = "   +  distTo [ v ]);                  StdOut . println ( "distTo["   +  w  +   "] = "   +  distTo [ w ]);                  return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertices ( Iterable < Integer >
 vertices
)
 
{

        
if
 
(
vertices 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
}

        
int
 V 
=
 marked
.
length
;

        
for
 
(
int
 v 
:
 vertices
)
 
{

            
if
 
(

<   0   ||  v  >=
 V
)
 
{

                
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

            
}

        
}

    
}

    
/**

     * Unit tests the {
@code
 BreadthFirstPaths} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        
// StdOut.println(G);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
BreadthFirstPaths
 bfs 
=
 
new
 
BreadthFirstPaths
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( bfs . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d (%d):  " ,  s ,  v ,  bfs . distTo ( v ));                  for   ( int  x  :  bfs . pathTo ( v ))   {                      if   ( x  ==  s )   StdOut . print ( x );                      else          StdOut . print ( "-"   +  x );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d (-):  not connected\n" ,  s ,  v );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/BST.java edu/princeton/cs/algs4/BST.java /******************************************************************************  *  Compilation:  javac BST.java  *  Execution:    java BST  *  Dependencies: StdIn.java StdOut.java Queue.java  *  Data files:   https://algs4.cs.princeton.edu/32bst/tinyST.txt    *  *  A symbol table implemented with a binary search tree.  *   *  % more tinyST.txt  *  S E A R C H E X A M P L E  *    *  % java BST < tinyST.txt  *  A 8  *  C 4  *  E 12  *  H 5  *  L 11  *  M 9  *  P 10  *  R 3  *  S 0  *  X 7  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  BST} class represents an ordered symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides ordered methods for finding the minimum,

 *  maximumfloorselectceiling.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  

 *  This implementation uses an (unbalanced) binary search tree.

 *  The putcontainsremoveminimum,

 *  maximumceilingfloorselect, and

 *  rank  operations each take Θ(n) time in the worst

 *  case, where n is the number of key-value pairs.

 *  The size and is-empty operations take Θ(1) time.

 *  The keys method takes Θ(n) time in the worst case.

 *  Construction takes Θ(1) time.

 *  

 *  For alternative implementations of the symbol table API, see {
@link
 ST},

 *  {
@link
 BinarySearchST}, {
@link
 SequentialSearchST}, {
@link
 RedBlackBST},

 *  {
@link
 SeparateChainingHashST}, and {
@link
 LinearProbingHashST},

 *  For additional documentation, see

 *  Section 3.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 BST
< Key   extends   Comparable < Key >
,
 
Value
>
 
{

    
private
 
Node
 root
;
             
// root of BST

    
private
 
class
 
Node
 
{

        
private
 
Key
 key
;
           
// sorted by key

        
private
 
Value
 val
;
         
// associated data

        
private
 
Node
 left
,
 right
;
  
// left and right subtrees

        
private
 
int
 size
;
          
// number of nodes in subtree

        
public
 
Node
(
Key
 key
,
 
Value
 val
,
 
int
 size
)
 
{

            
this
.
key 
=
 key
;

            
this
.
val 
=
 val
;

            
this
.
size 
=
 size
;

        
}

    
}

    
/**

     * Initializes an empty symbol table.

     */

    
public
 BST
()
 
{

    
}

    
/**

     * Returns true if this symbol table is empty.

     * 
@return
 {
@code
 true} if this symbol table is empty; {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 size
(
root
);

    
}

    
// return number of key-value pairs in BST rooted at x

    
private
 
int
 size
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
0
;

        
else
 
return
 x
.
size
;

    
}

    
/**

     * Does this symbol table contain the given key?

     *

     * 
@param
  key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key} and

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
/**

     * Returns the value associated with the given key.

     *

     * 
@param
  key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *         and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
return
 get
(
root
,
 key
);

    
}

    
private
 
Value
 get
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls get() with a null key”
);

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
      
(
cmp 
<   0 )   return  get ( x . left ,  key );          else   if   ( cmp  >
 
0
)
 
return
 get
(
x
.
right
,
 key
);

        
else
              
return
 x
.
val
;

    
}

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting the old 

     * value with the new value if the symbol table already contains the specified key.

     * Deletes the specified key (and its associated value) from this symbol table

     * if the specified value is {
@code
 null}.

     *

     * 
@param
  key the key

     * 
@param
  val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls put() with a null key”
);

        
if
 
(
val 
==
 
null
)
 
{

            delete
(
key
);

            
return
;

        
}

        root 
=
 put
(
root
,
 key
,
 val
);

        
assert
 check
();

    
}

    
private
 
Node
 put
(
Node
 x
,
 
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(

==
 
null
)
 
return
 
new
 
Node
(
key
,
 val
,
 
1
);

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
      
(
cmp 
<   0 )  x . left   =  put ( x . left ,   key ,  val );          else   if   ( cmp  >
 
0
)
 x
.
right 
=
 put
(
x
.
right
,
 key
,
 val
);

        
else
              x
.
val   
=
 val
;

        x
.
size 
=
 
1
 
+
 size
(
x
.
left
)
 
+
 size
(
x
.
right
);

        
return
 x
;

    
}

    
/**

     * Removes the smallest key and associated value from the symbol table.

     *

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Symbol table underflow”
);

        root 
=
 deleteMin
(
root
);

        
assert
 check
();

    
}

    
private
 
Node
 deleteMin
(
Node
 x
)
 
{

        
if
 
(
x
.
left 
==
 
null
)
 
return
 x
.
right
;

        x
.
left 
=
 deleteMin
(
x
.
left
);

        x
.
size 
=
 size
(
x
.
left
)
 
+
 size
(
x
.
right
)
 
+
 
1
;

        
return
 x
;

    
}

    
/**

     * Removes the largest key and associated value from the symbol table.

     *

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMax
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Symbol table underflow”
);

        root 
=
 deleteMax
(
root
);

        
assert
 check
();

    
}

    
private
 
Node
 deleteMax
(
Node
 x
)
 
{

        
if
 
(
x
.
right 
==
 
null
)
 
return
 x
.
left
;

        x
.
right 
=
 deleteMax
(
x
.
right
);

        x
.
size 
=
 size
(
x
.
left
)
 
+
 size
(
x
.
right
)
 
+
 
1
;

        
return
 x
;

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).    

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls delete() with a null key”
);

        root 
=
 delete
(
root
,
 key
);

        
assert
 check
();

    
}

    
private
 
Node
 delete
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
      
(
cmp 
<   0 )  x . left   =  delete ( x . left ,   key );          else   if   ( cmp  >
 
0
)
 x
.
right 
=
 delete
(
x
.
right
,
 key
);

        
else
 
{
 

            
if
 
(
x
.
right 
==
 
null
)
 
return
 x
.
left
;

            
if
 
(
x
.
left  
==
 
null
)
 
return
 x
.
right
;

            
Node
 t 
=
 x
;

            x 
=
 min
(
t
.
right
);

            x
.
right 
=
 deleteMin
(
t
.
right
);

            x
.
left 
=
 t
.
left
;

        
}
 

        x
.
size 
=
 size
(
x
.
left
)
 
+
 size
(
x
.
right
)
 
+
 
1
;

        
return
 x
;

    
}
 

    
/**

     * Returns the smallest key in the symbol table.

     *

     * 
@return
 the smallest key in the symbol table

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls min() with empty symbol table”
);

        
return
 min
(
root
).
key
;

    
}
 

    
private
 
Node
 min
(
Node
 x
)
 
{
 

        
if
 
(
x
.
left 
==
 
null
)
 
return
 x
;
 

        
else
                
return
 min
(
x
.
left
);
 

    
}
 

    
/**

     * Returns the largest key in the symbol table.

     *

     * 
@return
 the largest key in the symbol table

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls max() with empty symbol table”
);

        
return
 max
(
root
).
key
;

    
}
 

    
private
 
Node
 max
(
Node
 x
)
 
{

        
if
 
(
x
.
right 
==
 
null
)
 
return
 x
;
 

        
else
                 
return
 max
(
x
.
right
);
 

    
}
 

    
/**

     * Returns the largest key in the symbol table less than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the largest key in the symbol table less than or equal to {
@code
 key}

     * 
@throws
 NoSuchElementException if there is no such key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 floor
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to floor() is null”
);

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls floor() with empty symbol table”
);

        
Node
 x 
=
 floor
(
root
,
 key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“argument to floor() is too small”
);

        
else
 
return
 x
.
key
;

    
}
 

    
private
 
Node
 floor
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
 
(
cmp 
==
 
0
)
 
return
 x
;

        
if
 
(
cmp 
<    0 )   return  floor ( x . left ,  key );          Node  t  =  floor ( x . right ,  key );            if   ( t  !=   null )   return  t ;          else   return  x ;        }        public   Key  floor2 ( Key  key )   {          Key  x  =  floor2 ( root ,  key ,   null );          if   ( x  ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );          else   return  x ;      }      private   Key  floor2 ( Node  x ,   Key  key ,   Key  best )   {          if   ( x  ==   null )   return  best ;          int  cmp  =  key . compareTo ( x . key );          if        ( cmp   <   0 )   return  floor2 ( x . left ,  key ,  best );          else   if   ( cmp   >
 
0
)
 
return
 floor2
(
x
.
right
,
 key
,
 x
.
key
);

        
else
               
return
 x
.
key
;

    
}
 

    
/**

     * Returns the smallest key in the symbol table greater than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the smallest key in the symbol table greater than or equal to {
@code
 key}

     * 
@throws
 NoSuchElementException if there is no such key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 ceiling
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to ceiling() is null”
);

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls ceiling() with empty symbol table”
);

        
Node
 x 
=
 ceiling
(
root
,
 key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“argument to floor() is too large”
);

        
else
 
return
 x
.
key
;

    
}

    
private
 
Node
 ceiling
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

        
if
 
(
cmp 
==
 
0
)
 
return
 x
;

        
if
 
(
cmp 
<   0 )   {                Node  t  =  ceiling ( x . left ,  key );                if   ( t  !=   null )   return  t ;              else   return  x ;            }            return  ceiling ( x . right ,  key );        }        /**      * Return the key in the symbol table whose rank is { @code  k}.      * This is the (k+1)st smallest key in the symbol table.      *      *  @param   k the order statistic      *  @return  the key in the symbol table of rank { @code  k}      *  @throws  IllegalArgumentException unless { @code  k} is between 0 and      *        n–1

     */

    
public
 
Key
 select
(
int
 k
)
 
{

        
if
 
(

<   0   ||  k  >=
 size
())
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument to select() is invalid: ”
 
+
 k
);

        
}

        
Node
 x 
=
 select
(
root
,
 k
);

        
return
 x
.
key
;

    
}

    
// Return key of rank k. 

    
private
 
Node
 select
(
Node
 x
,
 
int
 k
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;
 

        
int
 t 
=
 size
(
x
.
left
);
 

        
if
      
(

>
 k
)
 
return
 select
(
x
.
left
,
  k
);
 

        
else
 
if
 
(

<  k )   return  select ( x . right ,  k - t - 1 );            else              return  x ;        }        /**      * Return the number of keys in the symbol table strictly less than { @code  key}.      *      *  @param   key the key      *  @return  the number of keys in the symbol table strictly less than { @code  key}      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   int  rank ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );          return  rank ( key ,  root );      }        // Number of keys in the subtree less than key.      private   int  rank ( Key  key ,   Node  x )   {          if   ( x  ==   null )   return   0 ;            int  cmp  =  key . compareTo ( x . key );            if        ( cmp  <   0 )   return  rank ( key ,  x . left );            else   if   ( cmp  >
 
0
)
 
return
 
1
 
+
 size
(
x
.
left
)
 
+
 rank
(
key
,
 x
.
right
);
 

        
else
              
return
 size
(
x
.
left
);
 

    
}
 

    
/**

     * Returns all keys in the symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     *

     * 
@return
 all keys in the symbol table

     */

    
public
 
Iterable
< Key >
 keys
()
 
{

        
if
 
(
isEmpty
())
 
return
 
new
 
Queue
< Key >
();

        
return
 keys
(
min
(),
 max
());

    
}

    
/**

     * Returns all keys in the symbol table in the given range,

     * as an {
@code
 Iterable}.

     *

     * 
@param
  lo minimum endpoint

     * 
@param
  hi maximum endpoint

     * 
@return
 all keys in the symbol table between {
@code
 lo} 

     *         (inclusive) and {
@code
 hi} (inclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *         is {
@code
 null}

     */

    
public
 
Iterable
< Key >
 keys
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to keys() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to keys() is null”
);

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        keys
(
root
,
 queue
,
 lo
,
 hi
);

        
return
 queue
;

    
}
 

    
private
 
void
 keys
(
Node
 x
,
 
Queue
< Key >
 queue
,
 
Key
 lo
,
 
Key
 hi
)
 
{
 

        
if
 
(

==
 
null
)
 
return
;
 

        
int
 cmplo 
=
 lo
.
compareTo
(
x
.
key
);
 

        
int
 cmphi 
=
 hi
.
compareTo
(
x
.
key
);
 

        
if
 
(
cmplo 
<   0 )  keys ( x . left ,  queue ,  lo ,  hi );            if   ( cmplo  <=   0   &&  cmphi  >=
 
0
)
 queue
.
enqueue
(
x
.
key
);
 

        
if
 
(
cmphi 
>
 
0
)
 keys
(
x
.
right
,
 queue
,
 lo
,
 hi
);
 

    
}
 

    
/**

     * Returns the number of keys in the symbol table in the given range.

     *

     * 
@param
  lo minimum endpoint

     * 
@param
  hi maximum endpoint

     * 
@return
 the number of keys in the symbol table between {
@code
 lo} 

     *         (inclusive) and {
@code
 hi} (inclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *         is {
@code
 null}

     */

    
public
 
int
 size
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to size() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to size() is null”
);

        
if
 
(
lo
.
compareTo
(
hi
)
 
>
 
0
)
 
return
 
0
;

        
if
 
(
contains
(
hi
))
 
return
 rank
(
hi
)
 

 rank
(
lo
)
 
+
 
1
;

        
else
              
return
 rank
(
hi
)
 

 rank
(
lo
);

    
}

    
/**

     * Returns the height of the BST (for debugging).

     *

     * 
@return
 the height of the BST (a 1-node tree has height 0)

     */

    
public
 
int
 height
()
 
{

        
return
 height
(
root
);

    
}

    
private
 
int
 height
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 

1
;

        
return
 
1
 
+
 
Math
.
max
(
height
(
x
.
left
),
 height
(
x
.
right
));

    
}

    
/**

     * Returns the keys in the BST in level order (for debugging).

     *

     * 
@return
 the keys in the BST in level order traversal

     */

    
public
 
Iterable
< Key >
 levelOrder
()
 
{

        
Queue
< Key >
 keys 
=
 
new
 
Queue
< Key >
();

        
Queue
< Node >
 queue 
=
 
new
 
Queue
< Node >
();

        queue
.
enqueue
(
root
);

        
while
 
(
!
queue
.
isEmpty
())
 
{

            
Node
 x 
=
 queue
.
dequeue
();

            
if
 
(

==
 
null
)
 
continue
;

            keys
.
enqueue
(
x
.
key
);

            queue
.
enqueue
(
x
.
left
);

            queue
.
enqueue
(
x
.
right
);

        
}

        
return
 keys
;

    
}

  
/*************************************************************************

    *  Check integrity of BST data structure.

    ***************************************************************************/

    
private
 
boolean
 check
()
 
{

        
if
 
(
!
isBST
())
            
StdOut
.
println
(
“Not in symmetric order”
);

        
if
 
(
!
isSizeConsistent
())
 
StdOut
.
println
(
“Subtree counts not consistent”
);

        
if
 
(
!
isRankConsistent
())
 
StdOut
.
println
(
“Ranks not consistent”
);

        
return
 isBST
()
 
&&
 isSizeConsistent
()
 
&&
 isRankConsistent
();

    
}

    
// does this binary tree satisfy symmetric order?

    
// Note: this test also ensures that data structure is a binary tree since order is strict

    
private
 
boolean
 isBST
()
 
{

        
return
 isBST
(
root
,
 
null
,
 
null
);

    
}

    
// is the tree rooted at x a BST with all keys strictly between min and max

    
// (if min or max is null, treat as empty constraint)

    
// Credit: Bob Dondero’s elegant solution

    
private
 
boolean
 isBST
(
Node
 x
,
 
Key
 min
,
 
Key
 max
)
 
{

        
if
 
(

==
 
null
)
 
return
 
true
;

        
if
 
(
min 
!=
 
null
 
&&
 x
.
key
.
compareTo
(
min
)
 
<=   0 )   return   false ;          if   ( max  !=   null   &&  x . key . compareTo ( max )   >=
 
0
)
 
return
 
false
;

        
return
 isBST
(
x
.
left
,
 min
,
 x
.
key
)
 
&&
 isBST
(
x
.
right
,
 x
.
key
,
 max
);

    
}
 

    
// are the size fields correct?

    
private
 
boolean
 isSizeConsistent
()
 
{
 
return
 isSizeConsistent
(
root
);
 
}

    
private
 
boolean
 isSizeConsistent
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
true
;

        
if
 
(
x
.
size 
!=
 size
(
x
.
left
)
 
+
 size
(
x
.
right
)
 
+
 
1
)
 
return
 
false
;

        
return
 isSizeConsistent
(
x
.
left
)
 
&&
 isSizeConsistent
(
x
.
right
);

    
}
 

    
// check that ranks are consistent

    
private
 
boolean
 isRankConsistent
()
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  size ();  i ++ )              if   ( i  !=  rank ( select ( i )))   return   false ;          for   ( Key  key  :  keys ())              if   ( key . compareTo ( select ( rank ( key )))   !=   0 )   return   false ;          return   true ;      }      /**      * Unit tests the { @code  BST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {           BST < String ,   Integer >
 st 
=
 
new
 BST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
for
 
(
String
 s 
:
 st
.
levelOrder
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

        
StdOut
.
println
();

        
for
 
(
String
 s 
:
 st
.
keys
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/BTree.java
edu/princeton/cs/algs4/BTree.java
/******************************************************************************

 *  Compilation:  javac BTree.java

 *  Execution:    java BTree

 *  Dependencies: StdOut.java

 *

 *  B-tree.

 *

 *  Limitations

 *  ———–

 *   –  Assumes M is even and M >= 4

 *   –  should b be an array of children or list (it would help with

 *      casting to make it a list)

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 BTree} class represents an ordered symbol table of generic

 *  key-value pairs.

 *  It supports the putgetcontains,

 *  size, and is-empty methods.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This implementation uses a B-tree. It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  The getput, and contains operations

 *  each make logm(n) probes in the worst case,

 *  where n is the number of key-value pairs

 *  and m is the branching factor.

 *  The size, and is-empty operations take constant time.

 *  Construction takes constant time.

 *  

 *  For additional documentation, see

 *  Section 6.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
BTree
< Key   extends   Comparable < Key >
,
 
Value
>
  
{

    
// max children per B-tree node = M-1

    
// (must be even and greater than 2)

    
private
 
static
 
final
 
int
 M 
=
 
4
;

    
private
 
Node
 root
;
       
// root of the B-tree

    
private
 
int
 height
;
      
// height of the B-tree

    
private
 
int
 n
;
           
// number of key-value pairs in the B-tree

    
// helper B-tree node data type

    
private
 
static
 
final
 
class
 
Node
 
{

        
private
 
int
 m
;
                             
// number of children

        
private
 
Entry
[]
 children 
=
 
new
 
Entry
[
M
];
   
// the array of children

        
// create a node with k children

        
private
 
Node
(
int
 k
)
 
{

            m 
=
 k
;

        
}

    
}

    
// internal nodes: only use key and next

    
// external nodes: only use key and value

    
private
 
static
 
class
 
Entry
 
{

        
private
 
Comparable
 key
;

        
private
 
final
 
Object
 val
;

        
private
 
Node
 next
;
     
// helper field to iterate over array entries

        
public
 
Entry
(
Comparable
 key
,
 
Object
 val
,
 
Node
 next
)
 
{

            
this
.
key  
=
 key
;

            
this
.
val  
=
 val
;

            
this
.
next 
=
 next
;

        
}

    
}

    
/**

     * Initializes an empty B-tree.

     */

    
public
 
BTree
()
 
{

        root 
=
 
new
 
Node
(
0
);

    
}

 

    
/**

     * Returns true if this symbol table is empty.

     * 
@return
 {
@code
 true} if this symbol table is empty; {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns the height of this B-tree (for debugging).

     *

     * 
@return
 the height of this B-tree

     */

    
public
 
int
 height
()
 
{

        
return
 height
;

    
}

    
/**

     * Returns the value associated with the given key.

     *

     * 
@param
  key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *         and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);

        
return
 search
(
root
,
 key
,
 height
);

    
}

    
private
 
Value
 search
(
Node
 x
,
 
Key
 key
,
 
int
 ht
)
 
{

        
Entry
[]
 children 
=
 x
.
children
;

        
// external node

        
if
 
(
ht 
==
 
0
)
 
{

            
for
 
(
int
 j 
=
 
0
;
 j 
<  x . m ;  j ++ )   {                  if   ( eq ( key ,  children [ j ]. key ))   return   ( Value )  children [ j ]. val ;              }          }          // internal node          else   {              for   ( int  j  =   0 ;  j  <  x . m ;  j ++ )   {                  if   ( j + 1   ==  x . m  ||  less ( key ,  children [ j + 1 ]. key ))                      return  search ( children [ j ]. next ,  key ,  ht - 1 );              }          }          return   null ;      }      /**      * Inserts the key-value pair into the symbol table, overwriting the old value      * with the new value if the key is already in the symbol table.      * If the value is { @code  null}, this effectively deletes the key from the symbol table.      *      *  @param   key the key      *  @param   val the value      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  put ( Key  key ,   Value  val )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument key to put() is null" );          Node  u  =  insert ( root ,  key ,  val ,  height );           n ++ ;          if   ( u  ==   null )   return ;          // need to split root          Node  t  =   new   Node ( 2 );         t . children [ 0 ]   =   new   Entry ( root . children [ 0 ]. key ,   null ,  root );         t . children [ 1 ]   =   new   Entry ( u . children [ 0 ]. key ,   null ,  u );         root  =  t ;         height ++ ;      }      private   Node  insert ( Node  h ,   Key  key ,   Value  val ,   int  ht )   {          int  j ;          Entry  t  =   new   Entry ( key ,  val ,   null );          // external node          if   ( ht  ==   0 )   {              for   ( j  =   0 ;  j  <  h . m ;  j ++ )   {                  if   ( less ( key ,  h . children [ j ]. key ))   break ;              }          }          // internal node          else   {              for   ( j  =   0 ;  j  <  h . m ;  j ++ )   {                  if   (( j + 1   ==  h . m )   ||  less ( key ,  h . children [ j + 1 ]. key ))   {                      Node  u  =  insert ( h . children [ j ++ ]. next ,  key ,  val ,  ht - 1 );                      if   ( u  ==   null )   return   null ;                     t . key  =  u . children [ 0 ]. key ;                     t . next  =  u ;                      break ;                  }              }          }          for   ( int  i  =  h . m ;  i  >
 j
;
 i

)

            h
.
children
[
i
]
 
=
 h
.
children
[
i

1
];

        h
.
children
[
j
]
 
=
 t
;

        h
.
m
++
;

        
if
 
(
h
.

<  M )   return   null ;          else           return  split ( h );      }      // split node in half      private   Node  split ( Node  h )   {          Node  t  =   new   Node ( M / 2 );         h . m  =  M / 2 ;          for   ( int  j  =   0 ;  j  <  M / 2 ;  j ++ )             t . children [ j ]   =  h . children [ M / 2 + j ];            return  t ;           }      /**      * Returns a string representation of this B-tree (for debugging).      *      *  @return  a string representation of this B-tree.      */      public   String  toString ()   {          return  toString ( root ,  height ,   "" )   +   "\n" ;      }      private   String  toString ( Node  h ,   int  ht ,   String  indent )   {          StringBuilder  s  =   new   StringBuilder ();          Entry []  children  =  h . children ;          if   ( ht  ==   0 )   {              for   ( int  j  =   0 ;  j  <  h . m ;  j ++ )   {                 s . append ( indent  +  children [ j ]. key  +   " "   +  children [ j ]. val  +   "\n" );              }          }          else   {              for   ( int  j  =   0 ;  j  <  h . m ;  j ++ )   {                  if   ( j  >
 
0
)
 s
.
append
(
indent 
+
 
“(”
 
+
 children
[
j
].
key 
+
 
“)\n”
);

                s
.
append
(
toString
(
children
[
j
].
next
,
 ht

1
,
 indent 
+
 
”     ”
));

            
}

        
}

        
return
 s
.
toString
();

    
}

    
// comparison functions – make Comparable instead of Key to avoid casts

    
private
 
boolean
 less
(
Comparable
 k1
,
 
Comparable
 k2
)
 
{

        
return
 k1
.
compareTo
(
k2
)
 
<   0 ;      }      private   boolean  eq ( Comparable  k1 ,   Comparable  k2 )   {          return  k1 . compareTo ( k2 )   ==   0 ;      }      /**      * Unit tests the { @code  BTree} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          BTree < String ,   String >
 st 
=
 
new
 
BTree
< String ,   String >
();

        st
.
put
(
“www.cs.princeton.edu”
,
 
“128.112.136.12”
);

        st
.
put
(
“www.cs.princeton.edu”
,
 
“128.112.136.11”
);

        st
.
put
(
“www.princeton.edu”
,
    
“128.112.128.15”
);

        st
.
put
(
“www.yale.edu”
,
         
“130.132.143.21”
);

        st
.
put
(
“www.simpsons.com”
,
     
“209.052.165.60”
);

        st
.
put
(
“www.apple.com”
,
        
“17.112.152.32”
);

        st
.
put
(
“www.amazon.com”
,
       
“207.171.182.16”
);

        st
.
put
(
“www.ebay.com”
,
         
“66.135.192.87”
);

        st
.
put
(
“www.cnn.com”
,
          
“64.236.16.20”
);

        st
.
put
(
“www.google.com”
,
       
“216.239.41.99”
);

        st
.
put
(
“www.nytimes.com”
,
      
“199.239.136.200”
);

        st
.
put
(
“www.microsoft.com”
,
    
“207.126.99.140”
);

        st
.
put
(
“www.dell.com”
,
         
“143.166.224.230”
);

        st
.
put
(
“www.slashdot.org”
,
     
“66.35.250.151”
);

        st
.
put
(
“www.espn.com”
,
         
“199.181.135.201”
);

        st
.
put
(
“www.weather.com”
,
      
“63.111.66.11”
);

        st
.
put
(
“www.yahoo.com”
,
        
“216.109.118.65”
);

        
StdOut
.
println
(
“cs.princeton.edu:  ”
 
+
 st
.
get
(
“www.cs.princeton.edu”
));

        
StdOut
.
println
(
“hardvardsucks.com: ”
 
+
 st
.
get
(
“www.harvardsucks.com”
));

        
StdOut
.
println
(
“simpsons.com:      ”
 
+
 st
.
get
(
“www.simpsons.com”
));

        
StdOut
.
println
(
“apple.com:         ”
 
+
 st
.
get
(
“www.apple.com”
));

        
StdOut
.
println
(
“ebay.com:          ”
 
+
 st
.
get
(
“www.ebay.com”
));

        
StdOut
.
println
(
“dell.com:          ”
 
+
 st
.
get
(
“www.dell.com”
));

        
StdOut
.
println
();

        
StdOut
.
println
(
“size:    ”
 
+
 st
.
size
());

        
StdOut
.
println
(
“height:  ”
 
+
 st
.
height
());

        
StdOut
.
println
(
st
);

        
StdOut
.
println
();

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Cat.java
edu/princeton/cs/algs4/Cat.java
/******************************************************************************

 *  Compilation:  javac Cat.java

 *  Execution:    java Cat input0.txt input1.txt … output.txt

 *  Dependencies: In.java Out.java

 *  Data files:   https://algs4.cs.princeton.edu/11model/in1.txt

 *                https://algs4.cs.princeton.edu/11model/in2.txt

 *

 *  Reads in text files specified as the first command-line 

 *  arguments, concatenates them, and writes the result to

 *  filename specified as the last command-line arguments.

 *

 *  % more in1.txt

 *  This is

 *

 *  % more in2.txt 

 *  a tiny

 *  test.

 * 

 *  % java Cat in1.txt in2.txt out.txt

 *

 *  % more out.txt

 *  This is

 *  a tiny

 *  test.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Cat} class provides a client for concatenating the results

 *  of several text files.

 *  

 *  For additional documentation, see Section 1.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Cat
 
{
 

    
// this class should not be instantiated

    
private
 
Cat
()
 
{
 
}

    
/**

     * Reads in a sequence of text files specified as the first command-line

     * arguments, concatenates them, and writes the results to the file

     * specified as the last command-line argument.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{
 

        
Out
 out 
=
 
new
 
Out
(
args
[
args
.
length 

 
1
]);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  args . length  -   1 ;  i ++ )   {              In  in  =   new   In ( args [ i ]);              String  s  =  in . readAll ();             out . println ( s );             in . close ();          }         out . close ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/CC.java edu/princeton/cs/algs4/CC.java /******************************************************************************  *  Compilation:  javac CC.java  *  Execution:    java CC filename.txt  *  Dependencies: Graph.java StdOut.java Queue.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *                https://algs4.cs.princeton.edu/41graph/largeG.txt  *  *  Compute connected components using depth first search.  *  Runs in O(E + V) time.  *  *  % java CC tinyG.txt  *  3 components  *  0 1 2 3 4 5 6  *  7 8   *  9 10 11 12  *  *  % java CC mediumG.txt   *  1 components  *  0 1 2 3 4 5 6 7 8 9 10 ...  *  *  % java -Xss50m CC largeG.txt   *  1 components  *  0 1 2 3 4 5 6 7 8 9 10 ...  *  *  Note: This implementation uses a recursive DFS. To avoid needing  *        a potentially very large stack size, replace with a non-recurisve  *        DFS ala NonrecursiveDFS.java.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  CC} class represents a data type for   *  determining the connected components in an undirected graph.  *  The id operation determines in which connected component

 *  a given vertex lies; the connected operation

 *  determines whether two vertices are in the same connected component;

 *  the count operation determines the number of connected

 *  components; and the size operation determines the number

 *  of vertices in the connect component containing a given vertex.

 *  The component identifier of a connected component is one of the

 *  vertices in the connected component: two vertices have the same component

 *  identifier if and only if they are in the same connected component.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time,

 *  where V is the number of vertices and E is the

 *  number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  For additional documentation, see 

 *  Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 CC 
{

    
private
 
boolean
[]
 marked
;
   
// marked[v] = has vertex v been marked?

    
private
 
int
[]
 id
;
           
// id[v] = id of connected component containing v

    
private
 
int
[]
 size
;
         
// size[id] = number of vertices in given component

    
private
 
int
 count
;
          
// number of connected components

    
/**

     * Computes the connected components of the undirected graph {
@code
 G}.

     *

     * 
@param
 G the undirected graph

     */

    
public
 CC
(
Graph
 G
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        id 
=
 
new
 
int
[
G
.
V
()];

        size 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( ! marked [ v ])   {                 dfs ( G ,  v );                 count ++ ;              }          }      }      /**      * Computes the connected components of the edge-weighted graph { @code  G}.      *      *  @param  G the edge-weighted graph      */      public  CC ( EdgeWeightedGraph  G )   {         marked  =   new   boolean [ G . V ()];         id  =   new   int [ G . V ()];         size  =   new   int [ G . V ()];          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              if   ( ! marked [ v ])   {                 dfs ( G ,  v );                 count ++ ;              }          }      }      // depth-first search for a Graph      private   void  dfs ( Graph  G ,   int  v )   {         marked [ v ]   =   true ;         id [ v ]   =  count ;         size [ count ] ++ ;          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])   {                 dfs ( G ,  w );              }          }      }      // depth-first search for an EdgeWeightedGraph      private   void  dfs ( EdgeWeightedGraph  G ,   int  v )   {         marked [ v ]   =   true ;         id [ v ]   =  count ;         size [ count ] ++ ;          for   ( Edge  e  :  G . adj ( v ))   {              int  w  =  e . other ( v );              if   ( ! marked [ w ])   {                 dfs ( G ,  w );              }          }      }      /**      * Returns the component id of the connected component containing vertex { @code  v}.      *      *  @param   v the vertex      *  @return  the component id of the connected component containing vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  id ( int  v )   {         validateVertex ( v );          return  id [ v ];      }      /**      * Returns the number of vertices in the connected component containing vertex { @code  v}.      *      *  @param   v the vertex      *  @return  the number of vertices in the connected component containing vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  size ( int  v )   {         validateVertex ( v );          return  size [ id [ v ]];      }      /**      * Returns the number of connected components in the graph { @code  G}.      *      *  @return  the number of connected components in the graph { @code  G}      */      public   int  count ()   {          return  count ;      }      /**      * Returns true if vertices { @code  v} and { @code  w} are in the same      * connected component.      *      *  @param   v one vertex      *  @param   w the other vertex      *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same      *         connected component; { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      */      public   boolean  connected ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  id ( v )   ==  id ( w );      }      /**      * Returns true if vertices { @code  v} and { @code  w} are in the same      * connected component.      *      *  @param   v one vertex      *  @param   w the other vertex      *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same      *         connected component; { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      *  @deprecated  Replaced by { @link  #connected(int, int)}.      */     @ Deprecated      public   boolean  areConnected ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  id ( v )   ==  id ( w );      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 CC} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        CC cc 
=
 
new
 CC
(
G
);

        
// number of connected components

        
int
 m 
=
 cc
.
count
();

        
StdOut
.
println
(

+
 
” components”
);

        
// compute list of vertices in each connected component

        
Queue
< Integer >
[]
 components 
=
 
(
Queue
< Integer >
[])
 
new
 
Queue
[
m
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {             components [ i ]   =   new   Queue < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             components [ cc . id ( v )]. enqueue ( v );          }          // print results          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  v  :  components [ i ])   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/ClosestPair.java edu/princeton/cs/algs4/ClosestPair.java /******************************************************************************  *  Compilation:  javac ClosestPair.java  *  Execution:    java ClosestPair < input.txt  *  Dependencies: Point2D.java  *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt  *                https://algs4.cs.princeton.edu/99hull/kw1260.txt  *    *  Given n points in the plane, find the closest pair in n log n time.  *  *  Note: could speed it up by comparing square of Euclidean distances  *  instead of Euclidean distances.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  *  The { @code  ClosestPair} data type computes a closest pair of points  *  in a set of n points in the plane and provides accessor methods 

 *  for getting the closest pair of points and the distance between them.

 *  The distance between two points is their Euclidean distance.

 *  

 *  This implementation uses a divide-and-conquer algorithm. 

 *  It runs in O(n log n) time in the worst case and uses

 *  O(n) extra space.

 *  

 *  See also {
@link
 FarthestPair}.

 *  

 *  For additional documentation, see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ClosestPair
 
{

    
// closest pair of points and their Euclidean distance

    
private
 
Point2D
 best1
,
 best2
;

    
private
 
double
 bestDistance 
=
 
Double
.
POSITIVE_INFINITY
;

    
/**

     * Computes the closest pair of points in the specified array of points.

     *

     * 
@param
  points the array of points

     * 
@throws
 IllegalArgumentException if {
@code
 points} is {
@code
 null} or if any

     *         entry in {
@code
 points[]} is {
@code
 null}

     */

    
public
 
ClosestPair
(
Point2D
[]
 points
)
 
{

        
if
 
(
points 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“constructor argument is null”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  points . length ;  i ++ )   {              if   ( points [ i ]   ==   null )   throw   new   IllegalArgumentException ( "array element "   +  i  +   " is null" );          }          int  n  =  points . length ;          if   ( n  <=   1 )   return ;          // sort by x-coordinate (breaking ties by y-coordinate)          Point2D []  pointsByX  =   new   Point2D [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             pointsByX [ i ]   =  points [ i ];          Arrays . sort ( pointsByX ,   Point2D . X_ORDER );          // check for coincident points          for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )   {              if   ( pointsByX [ i ]. equals ( pointsByX [ i + 1 ]))   {                 bestDistance  =   0.0 ;                 best1  =  pointsByX [ i ];                 best2  =  pointsByX [ i + 1 ];                  return ;              }          }          // sort by y-coordinate (but not yet sorted)           Point2D []  pointsByY  =   new   Point2D [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             pointsByY [ i ]   =  pointsByX [ i ];          // auxiliary array          Point2D []  aux  =   new   Point2D [ n ];         closest ( pointsByX ,  pointsByY ,  aux ,   0 ,  n - 1 );      }      // find closest pair of points in pointsByX[lo..hi]      // precondition:  pointsByX[lo..hi] and pointsByY[lo..hi] are the same sequence of points      // precondition:  pointsByX[lo..hi] sorted by x-coordinate      // postcondition: pointsByY[lo..hi] sorted by y-coordinate      private   double  closest ( Point2D []  pointsByX ,   Point2D []  pointsByY ,   Point2D []  aux ,   int  lo ,   int  hi )   {          if   ( hi  <=  lo )   return   Double . POSITIVE_INFINITY ;          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;          Point2D  median  =  pointsByX [ mid ];          // compute closest pair with both endpoints in left subarray or both in right subarray          double  delta1  =  closest ( pointsByX ,  pointsByY ,  aux ,  lo ,  mid );          double  delta2  =  closest ( pointsByX ,  pointsByY ,  aux ,  mid + 1 ,  hi );          double  delta  =   Math . min ( delta1 ,  delta2 );          // merge back so that pointsByY[lo..hi] are sorted by y-coordinate         merge ( pointsByY ,  aux ,  lo ,  mid ,  hi );          // aux[0..m-1] = sequence of points closer than delta, sorted by y-coordinate          int  m  =   0 ;          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              if   ( Math . abs ( pointsByY [ i ]. x ()   -  median . x ())   <  delta )                 aux [ m ++ ]   =  pointsByY [ i ];          }          // compare each point to its neighbors with y-coordinate closer than delta          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              // a geometric packing argument shows that this loop iterates at most 7 times              for   ( int  j  =  i + 1 ;   ( j  <  m )   &&   ( aux [ j ]. y ()   -  aux [ i ]. y ()   <  delta );  j ++ )   {                  double  distance  =  aux [ i ]. distanceTo ( aux [ j ]);                  if   ( distance  <  delta )   {                     delta  =  distance ;                      if   ( distance  <  bestDistance )   {                         bestDistance  =  delta ;                         best1  =  aux [ i ];                         best2  =  aux [ j ];                          // StdOut.println("better distance = " + delta + " from " + best1 + " to " + best2);                      }                  }              }          }          return  delta ;      }      /**      * Returns one of the points in the closest pair of points.      *      *  @return  one of the two points in the closest pair of points;      *         { @code  null} if no such point (because there are fewer than 2 points)      */      public   Point2D  either ()   {          return  best1 ;      }      /**      * Returns the other point in the closest pair of points.      *      *  @return  the other point in the closest pair of points      *         { @code  null} if no such point (because there are fewer than 2 points)      */      public   Point2D  other ()   {          return  best2 ;      }      /**      * Returns the Eucliden distance between the closest pair of points.      *      *  @return  the Euclidean distance between the closest pair of points      *         { @code  Double.POSITIVE_INFINITY} if no such pair of points      *         exist (because there are fewer than 2 points)      */      public   double  distance ()   {          return  bestDistance ;      }      // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }      // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]      // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays      private   static   void  merge ( Comparable []  a ,   Comparable []  aux ,   int  lo ,   int  mid ,   int  hi )   {          // copy to aux[]          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {             aux [ k ]   =  a [ k ];          }               // merge back to a[]           int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
              a
[
k
]
 
=
 aux
[
j
++
];

            
else
 
if
 
(

>
 hi
)
               a
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
less
(
aux
[
j
],
 aux
[
i
]))
 a
[
k
]
 
=
 aux
[
j
++
];

            
else
                           a
[
k
]
 
=
 aux
[
i
++
];

        
}

    
}

   
/**

     * Unit tests the {
@code
 ClosestPair} data type.

     * Reads in an integer {
@code
 n} and {
@code
 n} points (specified by

     * their x– and y-coordinates) from standard input;

     * computes a closest pair of points; and prints the pair to standard

     * output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        
Point2D
[]
 points 
=
 
new
 
Point2D
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              double  x  =   StdIn . readDouble ();              double  y  =   StdIn . readDouble ();             points [ i ]   =   new   Point2D ( x ,  y );          }          ClosestPair  closest  =   new   ClosestPair ( points );          StdOut . println ( closest . distance ()   +   " from "   +  closest . either ()   +   " to "   +  closest . other ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/CollisionSystem.java edu/princeton/cs/algs4/CollisionSystem.java /******************************************************************************  *  Compilation:  javac CollisionSystem.java  *  Execution:    java CollisionSystem n               (n random particles)  *                java CollisionSystem < input.txt     (from a file)   *  Dependencies: StdDraw.java Particle.java MinPQ.java  *  Data files:   https://algs4.cs.princeton.edu/61event/diffusion.txt  *                https://algs4.cs.princeton.edu/61event/diffusion2.txt  *                https://algs4.cs.princeton.edu/61event/diffusion3.txt  *                https://algs4.cs.princeton.edu/61event/brownian.txt  *                https://algs4.cs.princeton.edu/61event/brownian2.txt  *                https://algs4.cs.princeton.edu/61event/billiards5.txt  *                https://algs4.cs.princeton.edu/61event/pendulum.txt  *    *  Creates n random particles and simulates their motion according  *  to the laws of elastic collisions.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . Color ; /**  *  The { @code  CollisionSystem} class represents a collection of particles  *  moving in the unit box, according to the laws of elastic collision.  *  This event-based simulation relies on a priority queue.  *  

 *  For additional documentation, 

 *  see Section 6.1 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
CollisionSystem
 
{

    
private
 
static
 
final
 
double
 HZ 
=
 
0.5
;
    
// number of redraw events per clock tick

    
private
 
MinPQ
< Event >
 pq
;
          
// the priority queue

    
private
 
double
 t  
=
 
0.0
;
          
// simulation clock time

    
private
 
Particle
[]
 particles
;
     
// the array of particles

    
/**

     * Initializes a system with the specified collection of particles.

     * The individual particles will be mutated during the simulation.

     *

     * 
@param
  particles the array of particles

     */

    
public
 
CollisionSystem
(
Particle
[]
 particles
)
 
{

        
this
.
particles 
=
 particles
.
clone
();
   
// defensive copy

    
}

    
// updates priority queue with all new events for particle a

    
private
 
void
 predict
(
Particle
 a
,
 
double
 limit
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
// particle-particle collisions

        
for
 
(
int
 i 
=
 
0
;
 i 
<  particles . length ;  i ++ )   {              double  dt  =  a . timeToHit ( particles [ i ]);              if   ( t  +  dt  <=  limit )                 pq . insert ( new   Event ( t  +  dt ,  a ,  particles [ i ]));          }          // particle-wall collisions          double  dtX  =  a . timeToHitVerticalWall ();          double  dtY  =  a . timeToHitHorizontalWall ();          if   ( t  +  dtX  <=  limit )  pq . insert ( new   Event ( t  +  dtX ,  a ,   null ));          if   ( t  +  dtY  <=  limit )  pq . insert ( new   Event ( t  +  dtY ,   null ,  a ));      }      // redraw all particles      private   void  redraw ( double  limit )   {          StdDraw . clear ();          for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )   {             particles [ i ]. draw ();          }          StdDraw . show ();          StdDraw . pause ( 20 );          if   ( t  <  limit )   {             pq . insert ( new   Event ( t  +   1.0   /  HZ ,   null ,   null ));          }      }             /**      * Simulates the system of particles for the specified amount of time.      *      *  @param   limit the amount of time      */      public   void  simulate ( double  limit )   {                   // initialize PQ with collision events and redraw event         pq  =   new   MinPQ < Event >
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  particles . length ;  i ++ )   {             predict ( particles [ i ],  limit );          }         pq . insert ( new   Event ( 0 ,   null ,   null ));          // redraw event          // the main event-driven simulation loop          while   ( ! pq . isEmpty ())   {                // get impending event, discard if invalidated              Event  e  =  pq . delMin ();              if   ( ! e . isValid ())   continue ;              Particle  a  =  e . a ;              Particle  b  =  e . b ;              // physical collision, so update positions, and then simulation clock              for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )                 particles [ i ]. move ( e . time  -  t );             t  =  e . time ;              // process event              if        ( a  !=   null   &&  b  !=   null )  a . bounceOff ( b );                // particle-particle collision              else   if   ( a  !=   null   &&  b  ==   null )  a . bounceOffVerticalWall ();     // particle-wall collision              else   if   ( a  ==   null   &&  b  !=   null )  b . bounceOffHorizontalWall ();   // particle-wall collision              else   if   ( a  ==   null   &&  b  ==   null )  redraw ( limit );                 // redraw event              // update the priority queue with new collisions involving a or b             predict ( a ,  limit );             predict ( b ,  limit );          }      }     /***************************************************************************     *  An event during a particle collision simulation. Each event contains     *  the time at which it will occur (assuming no supervening actions)     *  and the particles a and b involved.     *     *    -  a and b both null:      redraw event     *    -  a null, b not null:     collision with vertical wall     *    -  a not null, b null:     collision with horizontal wall     *    -  a and b both not null:  binary collision between a and b     *     ***************************************************************************/      private   static   class   Event   implements   Comparable < Event >
 
{

        
private
 
final
 
double
 time
;
         
// time that event is scheduled to occur

        
private
 
final
 
Particle
 a
,
 b
;
       
// particles involved in event, possibly null

        
private
 
final
 
int
 countA
,
 countB
;
  
// collision counts at event creation

                

        

        
// create a new event to occur at time t involving a and b

        
public
 
Event
(
double
 t
,
 
Particle
 a
,
 
Particle
 b
)
 
{

            
this
.
time 
=
 t
;

            
this
.
a    
=
 a
;

            
this
.
b    
=
 b
;

            
if
 
(

!=
 
null
)
 countA 
=
 a
.
count
();

            
else
           countA 
=
 

1
;

            
if
 
(

!=
 
null
)
 countB 
=
 b
.
count
();

            
else
           countB 
=
 

1
;

        
}

        
// compare times when two events will occur

        
public
 
int
 compareTo
(
Event
 that
)
 
{

            
return
 
Double
.
compare
(
this
.
time
,
 that
.
time
);

        
}

        

        
// has any collision occurred between when event was created and now?

        
public
 
boolean
 isValid
()
 
{

            
if
 
(

!=
 
null
 
&&
 a
.
count
()
 
!=
 countA
)
 
return
 
false
;

            
if
 
(

!=
 
null
 
&&
 b
.
count
()
 
!=
 countB
)
 
return
 
false
;

            
return
 
true
;

        
}

   

    
}

    
/**

     * Unit tests the {
@code
 CollisionSystem} data type.

     * Reads in the particle collision system from a standard input

     * (or generates {
@code
 N} random particles if a command-line integer

     * is specified); simulates the system.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
StdDraw
.
setCanvasSize
(
600
,
 
600
);

        
// enable double buffering

        
StdDraw
.
enableDoubleBuffering
();

        
// the array of particles

        
Particle
[]
 particles
;

        
// create n random particles

        
if
 
(
args
.
length 
==
 
1
)
 
{

            
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

            particles 
=
 
new
 
Particle
[
n
];

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )                 particles [ i ]   =   new   Particle ();          }          // or read from standard input          else   {              int  n  =   StdIn . readInt ();             particles  =   new   Particle [ n ];              for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                  double  rx      =   StdIn . readDouble ();                  double  ry      =   StdIn . readDouble ();                  double  vx      =   StdIn . readDouble ();                  double  vy      =   StdIn . readDouble ();                  double  radius  =   StdIn . readDouble ();                  double  mass    =   StdIn . readDouble ();                  int  r          =   StdIn . readInt ();                  int  g          =   StdIn . readInt ();                  int  b          =   StdIn . readInt ();                  Color  color    =   new   Color ( r ,  g ,  b );                 particles [ i ]   =   new   Particle ( rx ,  ry ,  vx ,  vy ,  radius ,  mass ,  color );              }          }          // create collision system and simulate          CollisionSystem  system  =   new   CollisionSystem ( particles );         system . simulate ( 10000 );      }        } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Complex.java edu/princeton/cs/algs4/Complex.java /******************************************************************************  *  Compilation:  javac Complex.java  *  Execution:    java Complex  *  Dependencies: StdOut.java  *  *  Data type for complex numbers.  *  *  The data type is "immutable" so once you create and initialize  *  a Complex object, you cannot change it. The "final" keyword  *  when declaring re and im enforces this rule, making it a  *  compile-time error to change the .re or .im fields after  *  they've been initialized.  *  *  % java Complex  *  a            = 5.0 + 6.0i  *  b            = -3.0 + 4.0i  *  Re(a)        = 5.0  *  Im(a)        = 6.0  *  b + a        = 2.0 + 10.0i  *  a - b        = 8.0 + 2.0i  *  a * b        = -39.0 + 2.0i  *  b * a        = -39.0 + 2.0i  *  a / b        = 0.36 - 1.52i  *  (a / b) * b  = 5.0 + 6.0i  *  conj(a)      = 5.0 - 6.0i  *  |a|          = 7.810249675906654  *  tan(a)       = -6.685231390246571E-6 + 1.0000103108981198i  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Complex} class represents a complex number.  *  Complex numbers are immutable: their values cannot be changed after they  *  are created.  *  It includes methods for addition, subtraction, multiplication, division,  *  conjugation, and other common functions on complex numbers.  *  

 *  For additional documentation, see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Complex
 
{

    
private
 
final
 
double
 re
;
   
// the real part

    
private
 
final
 
double
 im
;
   
// the imaginary part

    
/**

     * Initializes a complex number from the specified real and imaginary parts.

     *

     * 
@param
 real the real part

     * 
@param
 imag the imaginary part

     */

    
public
 
Complex
(
double
 real
,
 
double
 imag
)
 
{

        re 
=
 real
;

        im 
=
 imag
;

    
}

    
/**

     * Returns a string representation of this complex number.

     *

     * 
@return
 a string representation of this complex number,

     *         of the form 34 – 56i.

     */

    
public
 
String
 toString
()
 
{

        
if
 
(
im 
==
 
0
)
 
return
 re 
+
 
“”
;

        
if
 
(
re 
==
 
0
)
 
return
 im 
+
 
“i”
;

        
if
 
(
im 
<    0 )   return  re  +   " - "   +   ( - im )   +   "i" ;          return  re  +   " + "   +  im  +   "i" ;      }      /**      * Returns the absolute value of this complex number.      * This quantity is also known as the modulus or magnitude.

     *

     * 
@return
 the absolute value of this complex number

     */

    
public
 
double
 abs
()
 
{

        
return
 
Math
.
hypot
(
re
,
 im
);

    
}

    
/**

     * Returns the phase of this complex number.

     * This quantity is also known as the angle or argument.

     *

     * 
@return
 the phase of this complex number, a real number between -pi and pi

     */

    
public
 
double
 phase
()
 
{

        
return
 
Math
.
atan2
(
im
,
 re
);

    
}

    
/**

     * Returns the sum of this complex number and the specified complex number.

     *

     * 
@param
  that the other complex number

     * 
@return
 the complex number whose value is {
@code
 (this + that)}

     */

    
public
 
Complex
 plus
(
Complex
 that
)
 
{

        
double
 real 
=
 
this
.
re 
+
 that
.
re
;

        
double
 imag 
=
 
this
.
im 
+
 that
.
im
;

        
return
 
new
 
Complex
(
real
,
 imag
);

    
}

    
/**

     * Returns the result of subtracting the specified complex number from

     * this complex number.

     *

     * 
@param
  that the other complex number

     * 
@return
 the complex number whose value is {
@code
 (this – that)}

     */

    
public
 
Complex
 minus
(
Complex
 that
)
 
{

        
double
 real 
=
 
this
.
re 

 that
.
re
;

        
double
 imag 
=
 
this
.
im 

 that
.
im
;

        
return
 
new
 
Complex
(
real
,
 imag
);

    
}

    
/**

     * Returns the product of this complex number and the specified complex number.

     *

     * 
@param
  that the other complex number

     * 
@return
 the complex number whose value is {
@code
 (this * that)}

     */

    
public
 
Complex
 times
(
Complex
 that
)
 
{

        
double
 real 
=
 
this
.
re 
*
 that
.
re 

 
this
.
im 
*
 that
.
im
;

        
double
 imag 
=
 
this
.
re 
*
 that
.
im 
+
 
this
.
im 
*
 that
.
re
;

        
return
 
new
 
Complex
(
real
,
 imag
);

    
}

    
/**

     * Returns the product of this complex number and the specified scalar.

     *

     * 
@param
  alpha the scalar

     * 
@return
 the complex number whose value is {
@code
 (alpha * this)}

     */

    
public
 
Complex
 scale
(
double
 alpha
)
 
{

        
return
 
new
 
Complex
(
alpha 
*
 re
,
 alpha 
*
 im
);

    
}

    
/**

     * Returns the product of this complex number and the specified scalar.

     *

     * 
@param
  alpha the scalar

     * 
@return
 the complex number whose value is {
@code
 (alpha * this)}

     * 
@deprecated
 Replaced by {
@link
 #scale(double)}.

     */

    @
Deprecated

    
public
 
Complex
 times
(
double
 alpha
)
 
{

        
return
 
new
 
Complex
(
alpha 
*
 re
,
 alpha 
*
 im
);

    
}

    
/**

     * Returns the complex conjugate of this complex number.

     *

     * 
@return
 the complex conjugate of this complex number

     */

    
public
 
Complex
 conjugate
()
 
{

        
return
 
new
 
Complex
(
re
,
 

im
);

    
}

    
/**

     * Returns the reciprocal of this complex number.

     *

     * 
@return
 the complex number whose value is {
@code
 (1 / this)}

     */

    
public
 
Complex
 reciprocal
()
 
{

        
double
 scale 
=
 re
*
re 
+
 im
*
im
;

        
return
 
new
 
Complex
(
re 
/
 scale
,
 

im 
/
 scale
);

    
}

    
/**

     * Returns the real part of this complex number.

     *

     * 
@return
 the real part of this complex number

     */

    
public
 
double
 re
()
 
{

        
return
 re
;

    
}

    
/**

     * Returns the imaginary part of this complex number.

     *

     * 
@return
 the imaginary part of this complex number

     */

    
public
 
double
 im
()
 
{

        
return
 im
;

    
}

    
/**

     * Returns the result of dividing the specified complex number into

     * this complex number.

     *

     * 
@param
  that the other complex number

     * 
@return
 the complex number whose value is {
@code
 (this / that)}

     */

    
public
 
Complex
 divides
(
Complex
 that
)
 
{

        
return
 
this
.
times
(
that
.
reciprocal
());

    
}

    
/**

     * Returns the complex exponential of this complex number.

     *

     * 
@return
 the complex exponential of this complex number

     */

    
public
 
Complex
 exp
()
 
{

        
return
 
new
 
Complex
(
Math
.
exp
(
re
)
 
*
 
Math
.
cos
(
im
),
 
Math
.
exp
(
re
)
 
*
 
Math
.
sin
(
im
));

    
}

    
/**

     * Returns the complex sine of this complex number.

     *

     * 
@return
 the complex sine of this complex number

     */

    
public
 
Complex
 sin
()
 
{

        
return
 
new
 
Complex
(
Math
.
sin
(
re
)
 
*
 
Math
.
cosh
(
im
),
 
Math
.
cos
(
re
)
 
*
 
Math
.
sinh
(
im
));

    
}

    
/**

     * Returns the complex cosine of this complex number.

     *

     * 
@return
 the complex cosine of this complex number

     */

    
public
 
Complex
 cos
()
 
{

        
return
 
new
 
Complex
(
Math
.
cos
(
re
)
 
*
 
Math
.
cosh
(
im
),
 

Math
.
sin
(
re
)
 
*
 
Math
.
sinh
(
im
));

    
}

    
/**

     * Returns the complex tangent of this complex number.

     *

     * 
@return
 the complex tangent of this complex number

     */

    
public
 
Complex
 tan
()
 
{

        
return
 sin
().
divides
(
cos
());

    
}

    

    
/**

     * Unit tests the {
@code
 Complex} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Complex
 a 
=
 
new
 
Complex
(
5.0
,
 
6.0
);

        
Complex
 b 
=
 
new
 
Complex
(

3.0
,
 
4.0
);

        
StdOut
.
println
(
“a            = ”
 
+
 a
);

        
StdOut
.
println
(
“b            = ”
 
+
 b
);

        
StdOut
.
println
(
“Re(a)        = ”
 
+
 a
.
re
());

        
StdOut
.
println
(
“Im(a)        = ”
 
+
 a
.
im
());

        
StdOut
.
println
(
“b + a        = ”
 
+
 b
.
plus
(
a
));

        
StdOut
.
println
(
“a – b        = ”
 
+
 a
.
minus
(
b
));

        
StdOut
.
println
(
“a * b        = ”
 
+
 a
.
times
(
b
));

        
StdOut
.
println
(
“b * a        = ”
 
+
 b
.
times
(
a
));

        
StdOut
.
println
(
“a / b        = ”
 
+
 a
.
divides
(
b
));

        
StdOut
.
println
(
“(a / b) * b  = ”
 
+
 a
.
divides
(
b
).
times
(
b
));

        
StdOut
.
println
(
“conj(a)      = ”
 
+
 a
.
conjugate
());

        
StdOut
.
println
(
“|a|          = ”
 
+
 a
.
abs
());

        
StdOut
.
println
(
“tan(a)       = ”
 
+
 a
.
tan
());

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Counter.java
edu/princeton/cs/algs4/Counter.java
/******************************************************************************

 *  Compilation:  javac Counter.java

 *  Execution:    java Counter n trials

 *  Dependencies: StdRandom.java StdOut.java

 *

 *  A mutable data type for an integer counter.

 *

 *  The test clients create n counters and performs trials increment

 *  operations on random counters.

 *

 * java Counter 6 600000

 *  100140 counter0

 *  100273 counter1

 *  99848 counter2

 *  100129 counter3

 *  99973 counter4

 *  99637 counter5

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Counter} class is a mutable data type to encapsulate a counter.

 *  

 *  For additional documentation,

 *  see Section 1.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Counter
 
implements
 
Comparable
< Counter >
 
{

    
private
 
final
 
String
 name
;
     
// counter name

    
private
 
int
 count 
=
 
0
;
         
// current value

    
/**

     * Initializes a new counter starting at 0, with the given id.

     *

     * 
@param
 id the name of the counter

     */

    
public
 
Counter
(
String
 id
)
 
{

        name 
=
 id
;

    
}
 

    
/**

     * Increments the counter by 1.

     */

    
public
 
void
 increment
()
 
{

        count
++
;

    
}
 

    
/**

     * Returns the current value of this counter.

     *

     * 
@return
 the current value of this counter

     */

    
public
 
int
 tally
()
 
{

        
return
 count
;

    
}
 

    
/**

     * Returns a string representation of this counter.

     *

     * 
@return
 a string representation of this counter

     */

    
public
 
String
 toString
()
 
{

        
return
 count 
+
 
” ”
 
+
 name
;

    
}
 

    
/**

     * Compares this counter to the specified counter.

     *

     * 
@param
  that the other counter

     * 
@return
 {
@code
 0} if the value of this counter equals

     *         the value of that counter; a negative integer if

     *         the value of this counter is less than the value of

     *         that counter; and a positive integer if the value

     *         of this counter is greater than the value of that

     *         counter

     */

    @
Override

    
public
 
int
 compareTo
(
Counter
 that
)
 
{

        
if
      
(
this
.
count 
<  that . count )   return   - 1 ;          else   if   ( this . count  >
 that
.
count
)
 
return
 
+
1
;

        
else
                              
return
  
0
;

    
}

    
/**

     * Reads two command-line integers n and trials; creates n counters;

     * increments trials counters at random; and prints results.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{
 

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 trials 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// create n counters

        
Counter
[]
 hits 
=
 
new
 
Counter
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             hits [ i ]   =   new   Counter ( "counter"   +  i );          }          // increment trials counters at random          for   ( int  t  =   0 ;  t  <  trials ;  t ++ )   {             hits [ StdRandom . uniform ( n )]. increment ();          }          // print results          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . println ( hits [ i ]);          }      }   }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Count.java edu/princeton/cs/algs4/Count.java /******************************************************************************  *  Compilation:  javac Count.java  *  Execution:    java Count alpha < input.txt  *  Dependencies: Alphabet.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/50strings/abra.txt  *                https://algs4.cs.princeton.edu/50strings/pi.txt  *  *  Create an alphabet specified on the command line, read in a   *  sequence of characters over that alphabet (ignoring characters  *  not in the alphabet), computes the frequency of occurrence of  *  each character, and print out the results.  *  *  %  java Count ABCDR < abra.txt   *  A 5  *  B 2  *  C 1  *  D 1  *  R 2  *  *  % java Count 0123456789 < pi.txt  *  0 99959  *  1 99757  *  2 100026  *  3 100230  *  4 100230  *  5 100359  *  6 99548  *  7 99800  *  8 99985  *  9 100106  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Count} class provides an { @link  Alphabet} client for reading  *  in a piece of text and computing the frequency of occurrence of each  *  character over a given alphabet.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Count
 
{

    
// Do not instantiate.

    
private
 
Count
()
 
{
 
}

    
/**

     * Reads in text from standard input; calculates the frequency of

     * occurrence of each character over the alphabet specified as a

     * commmand-line argument; and prints the frequencies to standard

     * output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Alphabet
 alphabet 
=
 
new
 
Alphabet
(
args
[
0
]);

        
final
 
int
 R 
=
 alphabet
.
radix
();

        
int
[]
 count 
=
 
new
 
int
[
R
];

        
while
 
(
StdIn
.
hasNextChar
())
 
{

            
char
 c 
=
 
StdIn
.
readChar
();

            
if
 
(
alphabet
.
contains
(
c
))

                count
[
alphabet
.
toIndex
(
c
)]
++
;

        
}

        
for
 
(
int
 c 
=
 
0
;
 c 
<  R ;  c ++ )              StdOut . println ( alphabet . toChar ( c )   +   " "   +  count [ c ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/CPM.java edu/princeton/cs/algs4/CPM.java /******************************************************************************  *  Compilation:  javac CPM.java  *  Execution:    java CPM < input.txt  *  Dependencies: EdgeWeightedDigraph.java AcyclicDigraphLP.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/44sp/jobsPC.txt  *  *  Critical path method.  *  *  % java CPM < jobsPC.txt  *   job   start  finish  *  --------------------  *     0     0.0    41.0  *     1    41.0    92.0  *     2   123.0   173.0  *     3    91.0   127.0  *     4    70.0   108.0  *     5     0.0    45.0  *     6    70.0    91.0  *     7    41.0    73.0  *     8    91.0   123.0  *     9    41.0    70.0  *  Finish time:   173.0  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  CPM} class provides a client that solves the  *  parallel precedence-constrained job scheduling problem  *  via the critical path method. It reduces the problem

 *  to the longest-paths problem in edge-weighted DAGs.

 *  It builds an edge-weighted digraph (which must be a DAG)

 *  from the job-scheduling problem specification,

 *  finds the longest-paths tree, and computes the longest-paths

 *  lengths (which are precisely the start times for each job).

 *  

 *  This implementation uses {
@link
 AcyclicLP} to find a longest

 *  path in a DAG.

 *  The program takes Θ(V + E) time in

 *  the worst case, where V is the number of jobs and

 *  E is the number of precedence constraints.

 *  

 *  For additional documentation,

 *  see Section 4.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 CPM 
{

    
// this class cannot be instantiated

    
private
 CPM
()
 
{
 
}

    
/**

     *  Reads the precedence constraints from standard input

     *  and prints a feasible schedule to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// number of jobs

        
int
 n 
=
 
StdIn
.
readInt
();

        
// source and sink

        
int
 source 
=
 
2
*
n
;

        
int
 sink   
=
 
2
*

+
 
1
;

        
// build network

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
2
*

+
 
2
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              double  duration  =   StdIn . readDouble ();             G . addEdge ( new   DirectedEdge ( source ,  i ,   0.0 ));             G . addEdge ( new   DirectedEdge ( i + n ,  sink ,   0.0 ));             G . addEdge ( new   DirectedEdge ( i ,  i + n ,     duration ));              // precedence constraints              int  m  =   StdIn . readInt ();              for   ( int  j  =   0 ;  j  <  m ;  j ++ )   {                  int  precedent  =   StdIn . readInt ();                 G . addEdge ( new   DirectedEdge ( n + i ,  precedent ,   0.0 ));              }          }          // compute longest path          AcyclicLP  lp  =   new   AcyclicLP ( G ,  source );          // print results          StdOut . println ( " job   start  finish" );          StdOut . println ( "--------------------" );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . printf ( "%4d %7.1f %7.1f\n" ,  i ,  lp . distTo ( i ),  lp . distTo ( i + n ));          }          StdOut . printf ( "Finish time: %7.1f\n" ,  lp . distTo ( sink ));      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Cycle.java edu/princeton/cs/algs4/Cycle.java /******************************************************************************  *  Compilation:  javac Cycle.java  *  Execution:    java  Cycle filename.txt  *  Dependencies: Graph.java Stack.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *                https://algs4.cs.princeton.edu/41graph/largeG.txt    *  *  Identifies a cycle.  *  Runs in O(E + V) time.  *  *  % java Cycle tinyG.txt  *  3 4 5 3   *   *  % java Cycle mediumG.txt   *  15 0 225 15   *   *  % java Cycle largeG.txt   *  996673 762 840164 4619 785187 194717 996673   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Cycle} class represents a data type for   *  determining whether an undirected graph has a simple cycle.  *  The hasCycle operation determines whether the graph has

 *  a cycle and, if so, the cycle operation returns one.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  (The depth-first search part takes only O(V) time;

 *  however, checking for self-loops and parallel edges takes

 *  Θ(V + E) time in the worst case.)

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  

 *  For additional documentation, see

 *  Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Cycle
 
{

    
private
 
boolean
[]
 marked
;

    
private
 
int
[]
 edgeTo
;

    
private
 
Stack
< Integer >
 cycle
;

    
/**

     * Determines whether the undirected graph {
@code
 G} has a cycle and,

     * if so, finds such a cycle.

     *

     * 
@param
 G the undirected graph

     */

    
public
 
Cycle
(
Graph
 G
)
 
{

        
if
 
(
hasSelfLoop
(
G
))
 
return
;

        
if
 
(
hasParallelEdges
(
G
))
 
return
;

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( ! marked [ v ])                 dfs ( G ,   - 1 ,  v );      }      // does this graph have a self loop?      // side effect: initialize cycle to be self loop      private   boolean  hasSelfLoop ( Graph  G )   {          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  :  G . adj ( v ))   {                  if   ( v  ==  w )   {                     cycle  =   new   Stack < Integer >
();

                    cycle
.
push
(
v
);

                    cycle
.
push
(
v
);

                    
return
 
true
;

                
}

            
}

        
}

        
return
 
false
;

    
}

    
// does this graph have two parallel edges?

    
// side effect: initialize cycle to be two parallel edges

    
private
 
boolean
 hasParallelEdges
(
Graph
 G
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              // check for parallel edges incident to v              for   ( int  w  :  G . adj ( v ))   {                  if   ( marked [ w ])   {                     cycle  =   new   Stack < Integer >
();

                    cycle
.
push
(
v
);

                    cycle
.
push
(
w
);

                    cycle
.
push
(
v
);

                    
return
 
true
;

                
}

                marked
[
w
]
 
=
 
true
;

            
}

            
// reset so marked[v] = false for all v

            
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

                marked
[
w
]
 
=
 
false
;

            
}

        
}

        
return
 
false
;

    
}

    
/**

     * Returns true if the graph {
@code
 G} has a cycle.

     *

     * 
@return
 {
@code
 true} if the graph has a cycle; {
@code
 false} otherwise

     */

    
public
 
boolean
 hasCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

     
/**

     * Returns a cycle in the graph {
@code
 G}.

     * 
@return
 a cycle if the graph {
@code
 G} has a cycle,

     *         and {
@code
 null} otherwise

     */

    
public
 
Iterable
< Integer >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
private
 
void
 dfs
(
Graph
 G
,
 
int
 u
,
 
int
 v
)
 
{

        marked
[
v
]
 
=
 
true
;

        
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

            
// short circuit if cycle already found

            
if
 
(
cycle 
!=
 
null
)
 
return
;

            
if
 
(
!
marked
[
w
])
 
{

                edgeTo
[
w
]
 
=
 v
;

                dfs
(
G
,
 v
,
 w
);

            
}

            
// check for cycle (but disregard reverse of edge leading to v)

            
else
 
if
 
(

!=
 u
)
 
{

                cycle 
=
 
new
 
Stack
< Integer >
();

                
for
 
(
int
 x 
=
 v
;
 x 
!=
 w
;
 x 
=
 edgeTo
[
x
])
 
{

                    cycle
.
push
(
x
);

                
}

                cycle
.
push
(
w
);

                cycle
.
push
(
v
);

            
}

        
}

    
}

    
/**

     * Unit tests the {
@code
 Cycle} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        
Cycle
 finder 
=
 
new
 
Cycle
(
G
);

        
if
 
(
finder
.
hasCycle
())
 
{

            
for
 
(
int
 v 
:
 finder
.
cycle
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“Graph is acyclic”
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Date.java
edu/princeton/cs/algs4/Date.java
/******************************************************************************

 *  Compilation:  javac Date.java

 *  Execution:    java Date

 *  Dependencies: StdOut.java

 *

 *  An immutable data type for dates.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Date} class is an immutable data type to encapsulate a

 *  date (day, month, and year).

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Date
 
implements
 
Comparable
< Date >
 
{

    
private
 
static
 
final
 
int
[]
 DAYS 
=
 
{
 
0
,
 
31
,
 
29
,
 
31
,
 
30
,
 
31
,
 
30
,
 
31
,
 
31
,
 
30
,
 
31
,
 
30
,
 
31
 
};

    
private
 
final
 
int
 month
;
   
// month (between 1 and 12)

    
private
 
final
 
int
 day
;
     
// day   (between 1 and DAYS[month]

    
private
 
final
 
int
 year
;
    
// year

   
/**

     * Initializes a new date from the month, day, and year.

     * 
@param
 month the month (between 1 and 12)

     * 
@param
 day the day (between 1 and 28-31, depending on the month)

     * 
@param
 year the year

     * 
@throws
 IllegalArgumentException if this date is invalid

     */

    
public
 
Date
(
int
 month
,
 
int
 day
,
 
int
 year
)
 
{

        
if
 
(
!
isValid
(
month
,
 day
,
 year
))
 
throw
 
new
 
IllegalArgumentException
(
“Invalid date”
);

        
this
.
month 
=
 month
;

        
this
.
day   
=
 day
;

        
this
.
year  
=
 year
;

    
}

    
/**

     * Initializes new date specified as a string in form MM/DD/YYYY.

     * 
@param
 date the string representation of this date

     * 
@throws
 IllegalArgumentException if this date is invalid

     */

    
public
 
Date
(
String
 date
)
 
{

        
String
[]
 fields 
=
 date
.
split
(
“/”
);

        
if
 
(
fields
.
length 
!=
 
3
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Invalid date”
);

        
}

        month 
=
 
Integer
.
parseInt
(
fields
[
0
]);

        day   
=
 
Integer
.
parseInt
(
fields
[
1
]);

        year  
=
 
Integer
.
parseInt
(
fields
[
2
]);

        
if
 
(
!
isValid
(
month
,
 day
,
 year
))
 
throw
 
new
 
IllegalArgumentException
(
“Invalid date”
);

    
}

    
/**

     * Return the month.

     * 
@return
 the month (an integer between 1 and 12)

     */

    
public
 
int
 month
()
 
{

        
return
 month
;

    
}

    
/**

     * Returns the day.

     * 
@return
 the day (an integer between 1 and 31)

     */

    
public
 
int
 day
()
 
{

        
return
 day
;

    
}

    
/**

     * Returns the year.

     * 
@return
 the year

     */

    
public
 
int
 year
()
 
{

        
return
 year
;

    
}

    
// is the given date valid?

    
private
 
static
 
boolean
 isValid
(
int
 m
,
 
int
 d
,
 
int
 y
)
 
{

        
if
 
(

<   1   ||  m  >
 
12
)
      
return
 
false
;

        
if
 
(

<   1   ||  d  >
 DAYS
[
m
])
 
return
 
false
;

        
if
 
(

==
 
2
 
&&
 d 
==
 
29
 
&&
 
!
isLeapYear
(
y
))
 
return
 
false
;

        
return
 
true
;

    
}

    
// is y a leap year?

    
private
 
static
 
boolean
 isLeapYear
(
int
 y
)
 
{

        
if
 
(

%
 
400
 
==
 
0
)
 
return
 
true
;

        
if
 
(

%
 
100
 
==
 
0
)
 
return
 
false
;

        
return
 y 
%
 
4
 
==
 
0
;

    
}

    
/**

     * Returns the next date in the calendar.

     *

     * 
@return
 a date that represents the next day after this day

     */

    
public
 
Date
 next
()
 
{

        
if
 
(
isValid
(
month
,
 day 
+
 
1
,
 year
))
    
return
 
new
 
Date
(
month
,
 day 
+
 
1
,
 year
);

        
else
 
if
 
(
isValid
(
month 
+
 
1
,
 
1
,
 year
))
 
return
 
new
 
Date
(
month 
+
 
1
,
 
1
,
 year
);

        
else
                                  
return
 
new
 
Date
(
1
,
 
1
,
 year 
+
 
1
);

    
}

    
/**

     * Compares two dates chronologically.

     *

     * 
@param
  that the other date

     * 
@return
 {
@code
 true} if this date is after that date; {
@code
 false} otherwise

     */

    
public
 
boolean
 isAfter
(
Date
 that
)
 
{

        
return
 compareTo
(
that
)
 
>
 
0
;

    
}

    
/**

     * Compares two dates chronologically.

     *

     * 
@param
  that the other date

     * 
@return
 {
@code
 true} if this date is before that date; {
@code
 false} otherwise

     */

    
public
 
boolean
 isBefore
(
Date
 that
)
 
{

        
return
 compareTo
(
that
)
 
<   0 ;      }      /**      * Compares two dates chronologically.      *      *  @return  the value { @code  0} if the argument date is equal to this date;      *         a negative integer if this date is chronologically less than      *         the argument date; and a positive ineger if this date is chronologically      *         after the argument date      */     @ Override      public   int  compareTo ( Date  that )   {          if   ( this . year   <  that . year )    return   - 1 ;          if   ( this . year   >
 that
.
year
)
  
return
 
+
1
;

        
if
 
(
this
.
month 
<  that . month )   return   - 1 ;          if   ( this . month  >
 that
.
month
)
 
return
 
+
1
;

        
if
 
(
this
.
day   
<  that . day )     return   - 1 ;          if   ( this . day    >
 that
.
day
)
   
return
 
+
1
;

        
return
 
0
;

    
}

    
/**

     * Returns a string representation of this date.

     *

     * 
@return
 the string representation in the format MM/DD/YYYY

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
return
 month 
+
 
“/”
 
+
 day 
+
 
“/”
 
+
 year
;

    
}

    
/**

     * Compares this date to the specified date.

     *

     * 
@param
  other the other date

     * 
@return
 {
@code
 true} if this date equals {
@code
 other}; {
@code
 false} otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
Date
 that 
=
 
(
Date
)
 other
;

        
return
 
(
this
.
month 
==
 that
.
month
)
 
&&
 
(
this
.
day 
==
 that
.
day
)
 
&&
 
(
this
.
year 
==
 that
.
year
);

    
}

    
/**

     * Returns an integer hash code for this date.

     *

     * 
@return
 an integer hash code for this date

     */

    @
Override

    
public
 
int
 hashCode
()
 
{

        
return
 day 
+
 
31
*
month 
+
 
31
*
12
*
year
;

    
}

    
/**

     * Unit tests the {
@code
 Date} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Date
 today 
=
 
new
 
Date
(
2
,
 
25
,
 
2004
);

        
StdOut
.
println
(
today
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<   10 ;  i ++ )   {             today  =  today . next ();              StdOut . println ( today );          }          StdOut . println ( today . isAfter ( today . next ()));          StdOut . println ( today . isAfter ( today ));          StdOut . println ( today . next (). isAfter ( today ));          Date  birthday  =   new   Date ( 10 ,   16 ,   1971 );          StdOut . println ( birthday );          for   ( int  i  =   0 ;  i  <   10 ;  i ++ )   {             birthday  =  birthday . next ();              StdOut . println ( birthday );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DeDup.java edu/princeton/cs/algs4/DeDup.java /******************************************************************************  *  Compilation:  javac DeDup.java  *  Execution:    java DeDup < input.txt  *  Dependencies: SET StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt  *  *  Read in a list of words from standard input and print out  *  each word, removing any duplicates.  *  *  % more tinyTale.txt   *  it was the best of times it was the worst of times   *  it was the age of wisdom it was the age of foolishness   *  it was the epoch of belief it was the epoch of incredulity   *  it was the season of light it was the season of darkness   *  it was the spring of hope it was the winter of despair  *  *  % java DeDup < tinyTale.txt   *  it  *  was  *  the  *  best  *  of  *  times  *  worst  *  age  *  wisdom  *  ...  *  winter  *  despair  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DeDup} class provides a client for reading in a sequence of  *  words from standard input and printing each word, removing any duplicates.  *  It is useful as a test client for various symbol table implementations.  *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DeDup
 
{
  

    
// Do not instantiate.

    
private
 
DeDup
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        SET
< String >
 set 
=
 
new
 SET
< String >
();

        
// read in strings and add to set

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            
if
 
(
!
set
.
contains
(
key
))
 
{

                set
.
add
(
key
);

                
StdOut
.
println
(
key
);

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/DegreesOfSeparation.java
edu/princeton/cs/algs4/DegreesOfSeparation.java
/******************************************************************************

 *  Compilation:  javac DegreesOfSeparation.java

 *  Execution:    java DegreesOfSeparation filename delimiter source

 *  Dependencies: SymbolGraph.java Graph.java BreadthFirstPaths.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/41graph/routes.txt

 *                https://algs4.cs.princeton.edu/41graph/movies.txt

 *  

 *  

 *  %  java DegreesOfSeparation routes.txt ” ” “JFK”

 *  LAS

 *     JFK

 *     ORD

 *     DEN

 *     LAS

 *  DFW

 *     JFK

 *     ORD

 *     DFW

 *  EWR

 *     Not in database.

 *

 *  % java DegreesOfSeparation movies.txt “/” “Bacon, Kevin”

 *  Kidman, Nicole

 *     Bacon, Kevin

 *     Woodsman, The (2004)

 *     Grier, David Alan

 *     Bewitched (2005)

 *     Kidman, Nicole

 *  Grant, Cary

 *     Bacon, Kevin

 *     Planes, Trains & Automobiles (1987)

 *     Martin, Steve (I)

 *     Dead Men Don’t Wear Plaid (1982)

 *     Grant, Cary

 *

 *  % java DegreesOfSeparation movies.txt “/” “Animal House (1978)”

 *  Titanic (1997)

 *     Animal House (1978)

 *     Allen, Karen (I)

 *     Raiders of the Lost Ark (1981)

 *     Taylor, Rocky (I)

 *     Titanic (1997)

 *  To Catch a Thief (1955)

 *     Animal House (1978)

 *     Vernon, John (I)

 *     Topaz (1969)

 *     Hitchcock, Alfred (I)

 *     To Catch a Thief (1955)

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 DegreesOfSeparation} class provides a client for finding

 *  the degree of separation between one distinguished individual and

 *  every other individual in a social network.

 *  As an example, if the social network consists of actors in which

 *  two actors are connected by a link if they appeared in the same movie,

 *  and Kevin Bacon is the distinguished individual, then the client

 *  computes the Kevin Bacon number of every actor in the network.

 *  

 *  The running time is proportional to the number of individuals and

 *  connections in the network. If the connections are given implicitly,

 *  as in the movie network example (where every two actors are connected

 *  if they appear in the same movie), the efficiency of the algorithm

 *  is improved by allowing both movie and actor vertices and connecting

 *  each movie to all of the actors that appear in that movie.

 *  

 *  For additional documentation,

 *  see Section 4.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DegreesOfSeparation
 
{

    
// this class cannot be instantiated

    
private
 
DegreesOfSeparation
()
 
{
 
}

    
/**

     *  Reads in a social network from a file, and then repeatedly reads in

     *  individuals from standard input and prints out their degrees of

     *  separation.

     *  Takes three command-line arguments: the name of a file,

     *  a delimiter, and the name of the distinguished individual.

     *  Each line in the file contains the name of a vertex, followed by a

     *  list of the names of the vertices adjacent to that vertex,

     *  separated by the delimiter.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 filename  
=
 args
[
0
];

        
String
 delimiter 
=
 args
[
1
];

        
String
 source    
=
 args
[
2
];

        
// StdOut.println(“Source: ” + source);

        
SymbolGraph
 sg 
=
 
new
 
SymbolGraph
(
filename
,
 delimiter
);

        
Graph
 G 
=
 sg
.
graph
();

        
if
 
(
!
sg
.
contains
(
source
))
 
{

            
StdOut
.
println
(
source 
+
 
” not in database.”
);

            
return
;

        
}

        
int
 s 
=
 sg
.
indexOf
(
source
);

        
BreadthFirstPaths
 bfs 
=
 
new
 
BreadthFirstPaths
(
G
,
 s
);

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 sink 
=
 
StdIn
.
readLine
();

            
if
 
(
sg
.
contains
(
sink
))
 
{

                
int
 t 
=
 sg
.
indexOf
(
sink
);

                
if
 
(
bfs
.
hasPathTo
(
t
))
 
{

                    
for
 
(
int
 v 
:
 bfs
.
pathTo
(
t
))
 
{

                        
StdOut
.
println
(
”   ”
 
+
 sg
.
nameOf
(
v
));

                    
}

                
}

                
else
 
{

                    
StdOut
.
println
(
“Not connected”
);

                
}

            
}

            
else
 
{

                
StdOut
.
println
(
”   Not in database.”
);

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/DepthFirstDirectedPaths.java
edu/princeton/cs/algs4/DepthFirstDirectedPaths.java
/******************************************************************************

 *  Compilation:  javac DepthFirstDirectedPaths.java

 *  Execution:    java DepthFirstDirectedPaths digraph.txt s

 *  Dependencies: Digraph.java Stack.java

 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt

 *

 *  Determine reachability in a digraph from a given vertex using

 *  depth-first search.

 *  Runs in O(E + V) time.

 *

 *  % java DepthFirstDirectedPaths tinyDG.txt 3

 *  3 to 0:  3-5-4-2-0

 *  3 to 1:  3-5-4-2-0-1

 *  3 to 2:  3-5-4-2

 *  3 to 3:  3

 *  3 to 4:  3-5-4

 *  3 to 5:  3-5

 *  3 to 6:  not connected

 *  3 to 7:  not connected

 *  3 to 8:  not connected

 *  3 to 9:  not connected

 *  3 to 10:  not connected

 *  3 to 11:  not connected

 *  3 to 12:  not connected

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 DepthFirstDirectedPaths} class represents a data type for

 *  finding directed paths from a source vertex s to every

 *  other vertex in the digraph.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  See {
@link
 DepthFirstDirectedPaths} for a nonrecursive implementation.

 *  For additional documentation,  

 *  see Section 4.2 of  

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DepthFirstDirectedPaths
 
{

    
private
 
boolean
[]
 marked
;
  
// marked[v] = true iff v is reachable from s

    
private
 
int
[]
 edgeTo
;
      
// edgeTo[v] = last edge on path from s to v

    
private
 
final
 
int
 s
;
       
// source vertex

    
/**

     * Computes a directed path from {
@code
 s} to every other vertex in digraph {
@code
 G}.

     * 
@param
  G the digraph

     * 
@param
  s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DepthFirstDirectedPaths ( Digraph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         edgeTo  =   new   int [ G . V ()];          this . s  =  s ;         validateVertex ( s );         dfs ( G ,  s );      }      private   void  dfs ( Digraph  G ,   int  v )   {           marked [ v ]   =   true ;          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])   {                 edgeTo [ w ]   =  v ;                 dfs ( G ,  w );              }          }      }      /**      * Is there a directed path from the source vertex { @code  s} to vertex { @code  v}?      *  @param   v the vertex      *  @return  { @code  true} if there is a directed path from the source      *         vertex { @code  s} to vertex { @code  v}, { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }           /**      * Returns a directed path from the source vertex { @code  s} to vertex { @code  v}, or      * { @code  null} if no such path.      *  @param   v the vertex      *  @return  the sequence of vertices on a directed path from the source vertex      *         { @code  s} to vertex { @code  v}, as an Iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< Integer >
 path 
=
 
new
 
Stack
< Integer >
();

        
for
 
(
int
 x 
=
 v
;
 x 
!=
 s
;
 x 
=
 edgeTo
[
x
])

            path
.
push
(
x
);

        path
.
push
(
s
);

        
return
 path
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DepthFirstDirectedPaths} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
// StdOut.println(G);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
DepthFirstDirectedPaths
 dfs 
=
 
new
 
DepthFirstDirectedPaths
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( dfs . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d:  " ,  s ,  v );                  for   ( int  x  :  dfs . pathTo ( v ))   {                      if   ( x  ==  s )   StdOut . print ( x );                      else          StdOut . print ( "-"   +  x );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d:  not connected\n" ,  s ,  v );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DepthFirstOrder.java edu/princeton/cs/algs4/DepthFirstOrder.java /******************************************************************************  *  Compilation:  javac DepthFirstOrder.java  *  Execution:    java DepthFirstOrder digraph.txt  *  Dependencies: Digraph.java Queue.java Stack.java StdOut.java  *                EdgeWeightedDigraph.java DirectedEdge.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt  *                https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *  *  Compute preorder and postorder for a digraph or edge-weighted digraph.  *  Runs in O(E + V) time.  *  *  % java DepthFirstOrder tinyDAG.txt  *     v  pre post  *  --------------  *     0    0    8  *     1    3    2  *     2    9   10  *     3   10    9  *     4    2    0  *     5    1    1  *     6    4    7  *     7   11   11  *     8   12   12  *     9    5    6  *    10    8    5  *    11    6    4  *    12    7    3  *  Preorder:  0 5 4 1 6 9 11 12 10 2 3 7 8   *  Postorder: 4 5 1 12 11 10 9 6 0 3 2 7 8   *  Reverse postorder: 8 7 2 3 0 6 9 10 11 12 1 5 4   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DepthFirstOrder} class represents a data type for   *  determining depth-first search ordering of the vertices in a digraph  *  or edge-weighted digraph, including preorder, postorder, and reverse postorder.  *  

 *  This implementation uses depth-first search.

 *  Each constructor takes Θ(V + E) time,

 *  where V is the number of vertices and E is the

 *  number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DepthFirstOrder
 
{

    
private
 
boolean
[]
 marked
;
          
// marked[v] = has v been marked in dfs?

    
private
 
int
[]
 pre
;
                 
// pre[v]    = preorder  number of v

    
private
 
int
[]
 post
;
                
// post[v]   = postorder number of v

    
private
 
Queue
< Integer >
 preorder
;
   
// vertices in preorder

    
private
 
Queue
< Integer >
 postorder
;
  
// vertices in postorder

    
private
 
int
 preCounter
;
            
// counter or preorder numbering

    
private
 
int
 postCounter
;
           
// counter for postorder numbering

    
/**

     * Determines a depth-first order for the digraph {
@code
 G}.

     * 
@param
 G the digraph

     */

    
public
 
DepthFirstOrder
(
Digraph
 G
)
 
{

        pre    
=
 
new
 
int
[
G
.
V
()];

        post   
=
 
new
 
int
[
G
.
V
()];

        postorder 
=
 
new
 
Queue
< Integer >
();

        preorder  
=
 
new
 
Queue
< Integer >
();

        marked    
=
 
new
 
boolean
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( ! marked [ v ])  dfs ( G ,  v );          assert  check ();      }      /**      * Determines a depth-first order for the edge-weighted digraph { @code  G}.      *  @param  G the edge-weighted digraph      */      public   DepthFirstOrder ( EdgeWeightedDigraph  G )   {         pre     =   new   int [ G . V ()];         post    =   new   int [ G . V ()];         postorder  =   new   Queue < Integer >
();

        preorder  
=
 
new
 
Queue
< Integer >
();

        marked    
=
 
new
 
boolean
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( ! marked [ v ])  dfs ( G ,  v );      }      // run DFS in digraph G from vertex v and compute preorder/postorder      private   void  dfs ( Digraph  G ,   int  v )   {         marked [ v ]   =   true ;         pre [ v ]   =  preCounter ++ ;         preorder . enqueue ( v );          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])   {                 dfs ( G ,  w );              }          }         postorder . enqueue ( v );         post [ v ]   =  postCounter ++ ;      }      // run DFS in edge-weighted digraph G from vertex v and compute preorder/postorder      private   void  dfs ( EdgeWeightedDigraph  G ,   int  v )   {         marked [ v ]   =   true ;         pre [ v ]   =  preCounter ++ ;         preorder . enqueue ( v );          for   ( DirectedEdge  e  :  G . adj ( v ))   {              int  w  =  e . to ();              if   ( ! marked [ w ])   {                 dfs ( G ,  w );              }          }         postorder . enqueue ( v );         post [ v ]   =  postCounter ++ ;      }      /**      * Returns the preorder number of vertex { @code  v}.      *  @param   v the vertex      *  @return  the preorder number of vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  pre ( int  v )   {         validateVertex ( v );          return  pre [ v ];      }      /**      * Returns the postorder number of vertex { @code  v}.      *  @param   v the vertex      *  @return  the postorder number of vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  post ( int  v )   {         validateVertex ( v );          return  post [ v ];      }      /**      * Returns the vertices in postorder.      *  @return  the vertices in postorder, as an iterable of vertices      */      public   Iterable < Integer >
 post
()
 
{

        
return
 postorder
;

    
}

    
/**

     * Returns the vertices in preorder.

     * 
@return
 the vertices in preorder, as an iterable of vertices

     */

    
public
 
Iterable
< Integer >
 pre
()
 
{

        
return
 preorder
;

    
}

    
/**

     * Returns the vertices in reverse postorder.

     * 
@return
 the vertices in reverse postorder, as an iterable of vertices

     */

    
public
 
Iterable
< Integer >
 reversePost
()
 
{

        
Stack
< Integer >
 reverse 
=
 
new
 
Stack
< Integer >
();

        
for
 
(
int
 v 
:
 postorder
)

            reverse
.
push
(
v
);

        
return
 reverse
;

    
}

    
// check that pre() and post() are consistent with pre(v) and post(v)

    
private
 
boolean
 check
()
 
{

        
// check that post(v) is consistent with post()

        
int
 r 
=
 
0
;

        
for
 
(
int
 v 
:
 post
())
 
{

            
if
 
(
post
(
v
)
 
!=
 r
)
 
{

                
StdOut
.
println
(
“post(v) and post() inconsistent”
);

                
return
 
false
;

            
}

            r
++
;

        
}

        
// check that pre(v) is consistent with pre()

        r 
=
 
0
;

        
for
 
(
int
 v 
:
 pre
())
 
{

            
if
 
(
pre
(
v
)
 
!=
 r
)
 
{

                
StdOut
.
println
(
“pre(v) and pre() inconsistent”
);

                
return
 
false
;

            
}

            r
++
;

        
}

        
return
 
true
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DepthFirstOrder} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
DepthFirstOrder
 dfs 
=
 
new
 
DepthFirstOrder
(
G
);

        
StdOut
.
println
(
”   v  pre post”
);

        
StdOut
.
println
(
“————–”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              StdOut . printf ( "%4d %4d %4d\n" ,  v ,  dfs . pre ( v ),  dfs . post ( v ));          }          StdOut . print ( "Preorder:  " );          for   ( int  v  :  dfs . pre ())   {              StdOut . print ( v  +   " " );          }          StdOut . println ();          StdOut . print ( "Postorder: " );          for   ( int  v  :  dfs . post ())   {              StdOut . print ( v  +   " " );          }          StdOut . println ();          StdOut . print ( "Reverse postorder: " );          for   ( int  v  :  dfs . reversePost ())   {              StdOut . print ( v  +   " " );          }          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DepthFirstPaths.java edu/princeton/cs/algs4/DepthFirstPaths.java /******************************************************************************  *  Compilation:  javac DepthFirstPaths.java  *  Execution:    java DepthFirstPaths G s  *  Dependencies: Graph.java Stack.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt  *                https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *                https://algs4.cs.princeton.edu/41graph/largeG.txt  *  *  Run depth-first search on an undirected graph.  *  *  %  java Graph tinyCG.txt  *  6 8  *  0: 2 1 5   *  1: 0 2   *  2: 0 1 3 4   *  3: 5 4 2   *  4: 3 2   *  5: 3 0   *  *  % java DepthFirstPaths tinyCG.txt 0  *  0 to 0:  0  *  0 to 1:  0-2-1  *  0 to 2:  0-2  *  0 to 3:  0-2-3  *  0 to 4:  0-2-3-4  *  0 to 5:  0-2-3-5  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DepthFirstPaths} class represents a data type for finding  *  paths from a source vertex s to every other vertex

 *  in an undirected graph.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  For additional documentation, see

 *  Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DepthFirstPaths
 
{

    
private
 
boolean
[]
 marked
;
    
// marked[v] = is there an s-v path?

    
private
 
int
[]
 edgeTo
;
        
// edgeTo[v] = last edge on s-v path

    
private
 
final
 
int
 s
;
         
// source vertex

    
/**

     * Computes a path between {
@code
 s} and every other vertex in graph {
@code
 G}.

     * 
@param
 G the graph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DepthFirstPaths ( Graph  G ,   int  s )   {          this . s  =  s ;         edgeTo  =   new   int [ G . V ()];         marked  =   new   boolean [ G . V ()];         validateVertex ( s );         dfs ( G ,  s );      }      // depth first search from v      private   void  dfs ( Graph  G ,   int  v )   {         marked [ v ]   =   true ;          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])   {                 edgeTo [ w ]   =  v ;                 dfs ( G ,  w );              }          }      }      /**      * Is there a path between the source vertex { @code  s} and vertex { @code  v}?      *  @param  v the vertex      *  @return  { @code  true} if there is a path, { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      /**      * Returns a path between the source vertex { @code  s} and vertex { @code  v}, or      * { @code  null} if no such path.      *  @param   v the vertex      *  @return  the sequence of vertices on a path between the source vertex      *         { @code  s} and vertex { @code  v}, as an Iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< Integer >
 path 
=
 
new
 
Stack
< Integer >
();

        
for
 
(
int
 x 
=
 v
;
 x 
!=
 s
;
 x 
=
 edgeTo
[
x
])

            path
.
push
(
x
);

        path
.
push
(
s
);

        
return
 path
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DepthFirstPaths} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
DepthFirstPaths
 dfs 
=
 
new
 
DepthFirstPaths
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( dfs . hasPathTo ( v ))   {                  StdOut . printf ( "%d to %d:  " ,  s ,  v );                  for   ( int  x  :  dfs . pathTo ( v ))   {                      if   ( x  ==  s )   StdOut . print ( x );                      else          StdOut . print ( "-"   +  x );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d:  not connected\n" ,  s ,  v );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DepthFirstSearch.java edu/princeton/cs/algs4/DepthFirstSearch.java /******************************************************************************  *  Compilation:  javac DepthFirstSearch.java  *  Execution:    java DepthFirstSearch filename.txt s  *  Dependencies: Graph.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *  *  Run depth first search on an undirected graph.  *  Runs in O(E + V) time.  *  *  % java DepthFirstSearch tinyG.txt 0  *  0 1 2 3 4 5 6   *  NOT connected  *  *  % java DepthFirstSearch tinyG.txt 9  *  9 10 11 12   *  NOT connected  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DepthFirstSearch} class represents a data type for   *  determining the vertices connected to a given source vertex s

 *  in an undirected graph. For versions that find the paths, see

 *  {
@link
 DepthFirstPaths} and {
@link
 BreadthFirstPaths}.

 *  

 *  This implementation uses depth-first search.

 *  See {
@link
 NonrecursiveDFS} for a non-recursive version.

 *  The constructor takes Θ(V + E) time in the worst

 *  case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph). 

 *  

 *  For additional documentation, see

 *  Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DepthFirstSearch
 
{

    
private
 
boolean
[]
 marked
;
    
// marked[v] = is there an s-v path?

    
private
 
int
 count
;
           
// number of vertices connected to s

    
/**

     * Computes the vertices in graph {
@code
 G} that are

     * connected to the source vertex {
@code
 s}.

     * 
@param
 G the graph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DepthFirstSearch ( Graph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         validateVertex ( s );         dfs ( G ,  s );      }      // depth first search from v      private   void  dfs ( Graph  G ,   int  v )   {         count ++ ;         marked [ v ]   =   true ;          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])   {                 dfs ( G ,  w );              }          }      }      /**      * Is there a path between the source vertex { @code  s} and vertex { @code  v}?      *  @param  v the vertex      *  @return  { @code  true} if there is a path, { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  marked ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      /**      * Returns the number of vertices connected to the source vertex { @code  s}.      *  @return  the number of vertices connected to the source vertex { @code  s}      */      public   int  count ()   {          return  count ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DepthFirstSearch} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
DepthFirstSearch
 search 
=
 
new
 
DepthFirstSearch
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( search . marked ( v ))                  StdOut . print ( v  +   " " );          }          StdOut . println ();          if   ( search . count ()   !=  G . V ())   StdOut . println ( "NOT connected" );          else                           StdOut . println ( "connected" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DigraphGenerator.java edu/princeton/cs/algs4/DigraphGenerator.java /******************************************************************************  *  Compilation:  javac DigraphGenerator.java  *  Execution:    java DigraphGenerator V E  *  Dependencies: Digraph.java  *  *  A digraph generator.  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DigraphGenerator} class provides static methods for creating  *  various digraphs, including Erdos-Renyi random digraphs, random DAGs,  *  random rooted trees, random rooted DAGs, random tournaments, path digraphs,  *  cycle digraphs, and the complete digraph.  *  

 *  For additional documentation, see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DigraphGenerator
 
{

    
private
 
static
 
final
 
class
 
Edge
 
implements
 
Comparable
< Edge >
 
{

        
private
 
final
 
int
 v
;

        
private
 
final
 
int
 w
;

        
private
 
Edge
(
int
 v
,
 
int
 w
)
 
{

            
this
.

=
 v
;

            
this
.

=
 w
;

        
}

        
public
 
int
 compareTo
(
Edge
 that
)
 
{

            
if
 
(
this
.

<  that . v )   return   - 1 ;              if   ( this . v  >
 that
.
v
)
 
return
 
+
1
;

            
if
 
(
this
.

<  that . w )   return   - 1 ;              if   ( this . w  >
 that
.
w
)
 
return
 
+
1
;

            
return
 
0
;

        
}

    
}

    
// this class cannot be instantiated

    
private
 
DigraphGenerator
()
 
{
 
}

    
/**

     * Returns a random simple digraph containing {
@code
 V} vertices and {
@code
 E} edges.

     * 
@param
 V the number of vertices

     * 
@param
 E the number of vertices

     * 
@return
 a random simple digraph on {
@code
 V} vertices, containing a total

     *     of {
@code
 E} edges

     * 
@throws
 IllegalArgumentException if no such simple digraph exists

     */

    
public
 
static
 
Digraph
 simple
(
int
 V
,
 
int
 E
)
 
{

        
if
 
(

>
 
(
long
)
 V
*
(
V

1
))
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<   0 )                throw   new   IllegalArgumentException ( "Too few edges" );          Digraph  G  =   new   Digraph ( V );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
while
 
(
G
.
E
()
 
<  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( v ,  w );              if   (( v  !=  w )   &&   ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( v ,  w );              }          }          return  G ;      }     /**      * Returns a random simple digraph on { @code  V} vertices, with an       * edge between any two vertices with probability { @code  p}. This is sometimes      * referred to as the Erdos-Renyi random digraph model.      * This implementations takes time propotional to V^2 (even if { @code  p} is small).      *  @param  V the number of vertices      *  @param  p the probability of choosing an edge      *  @return  a random simple digraph on { @code  V} vertices, with an edge between      *     any two vertices with probability { @code  p}      *  @throws  IllegalArgumentException if probability is not between 0 and 1      */      public   static   Digraph  simple ( int  V ,   double  p )   {          if   ( p  <   0.0   ||  p  >
 
1.0
)

            
throw
 
new
 
IllegalArgumentException
(
“Probability must be between 0 and 1”
);

        
Digraph
 G 
=
 
new
 
Digraph
(
V
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )              for   ( int  w  =   0 ;  w  <  V ;  w ++ )                  if   ( v  !=  w )                      if   ( StdRandom . bernoulli ( p ))                         G . addEdge ( v ,  w );          return  G ;      }      /**      * Returns the complete digraph on { @code  V} vertices.      * In a complete digraph, every pair of distinct vertices is connected      * by two antiparallel edges. There are { @code  V*(V-1)} edges.      *  @param  V the number of vertices      *  @return  the complete digraph on { @code  V} vertices      */      public   static   Digraph  complete ( int  V )   {          Digraph  G  =   new   Digraph ( V );          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              for   ( int  w  =   0 ;  w  <  V ;  w ++ )                      if   ( v  !=  w )  G . addEdge ( v ,  w );          return  G ;      }      /**      * Returns a random simple DAG containing { @code  V} vertices and { @code  E} edges.      * Note: it is not uniformly selected at random among all such DAGs.      *  @param  V the number of vertices      *  @param  E the number of vertices      *  @return  a random simple DAG on { @code  V} vertices, containing a total      *     of { @code  E} edges      *  @throws  IllegalArgumentException if no such simple DAG exists      */      public   static   Digraph  dag ( int  V ,   int  E )   {          if   ( E  >
 
(
long
)
 V
*
(
V

1
)
 
/
 
2
)
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<   0 )                    throw   new   IllegalArgumentException ( "Too few edges" );          Digraph  G  =   new   Digraph ( V );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
int
[]
 vertices 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          while   ( G . E ()   <  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( v ,  w );              if   (( v  <  w )   &&   ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( vertices [ v ],  vertices [ w ]);              }          }          return  G ;      }      /**      * Returns a random tournament digraph on { @code  V} vertices. A tournament digraph      * is a digraph in which, for every pair of vertices, there is one and only one      * directed edge connecting them. A tournament is an oriented complete graph.      *  @param  V the number of vertices      *  @return  a random tournament digraph on { @code  V} vertices      */      public   static   Digraph  tournament ( int  V )   {          Digraph  G  =   new   Digraph ( V );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  =  v + 1 ;  w  <  G . V ();  w ++ )   {                  if   ( StdRandom . bernoulli ( 0.5 ))  G . addEdge ( v ,  w );                  else                           G . addEdge ( w ,  v );              }          }          return  G ;      }      /**      * Returns a complete rooted-in DAG on { @code  V} vertices.      * A rooted in-tree is a DAG in which there is a single vertex      * reachable from every other vertex. A complete rooted in-DAG      * has V*(V-1)/2 edges.      *  @param  V the number of vertices      *  @return  a complete rooted-in DAG on { @code  V} vertices      */      public   static   Digraph  completeRootedInDAG ( int  V )   {          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V ;  i ++ )              for   ( int  j  =  i + 1 ;  j  <  V ;  j ++ )                  G . addEdge ( vertices [ i ],  vertices [ j ]);          return  G ;      }      /**      * Returns a random rooted-in DAG on { @code  V} vertices and { @code  E} edges.      * A rooted in-tree is a DAG in which there is a single vertex      * reachable from every other vertex.      * The DAG returned is not chosen uniformly at random among all such DAGs.      *  @param  V the number of vertices      *  @param  E the number of edges      *  @return  a random rooted-in DAG on { @code  V} vertices and { @code  E} edges      */      public   static   Digraph  rootedInDAG ( int  V ,   int  E )   {          if   ( E  >
 
(
long
)
 V
*
(
V

1
)
 
/
 
2
)
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<  V - 1 )                  throw   new   IllegalArgumentException ( "Too few edges" );          Digraph  G  =   new   Digraph ( V );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
// fix a topological order

        
int
[]
 vertices 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          // one edge pointing from each vertex, other than the root = vertices[V-1]          for   ( int  v  =   0 ;  v  <  V - 1 ;  v ++ )   {              int  w  =   StdRandom . uniform ( v + 1 ,  V );              Edge  e  =   new   Edge ( v ,  w );             set . add ( e );             G . addEdge ( vertices [ v ],  vertices [ w ]);          }          while   ( G . E ()   <  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( v ,  w );              if   (( v  <  w )   &&   ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( vertices [ v ],  vertices [ w ]);              }          }          return  G ;      }      /**      * Returns a complete rooted-out DAG on { @code  V} vertices.      * A rooted out-tree is a DAG in which every vertex is reachable      * from a single vertex. A complete rooted in-DAG has V*(V-1)/2 edges.      *  @param  V the number of vertices      *  @return  a complete rooted-out DAG on { @code  V} vertices      */      public   static   Digraph  completeRootedOutDAG ( int  V )   {          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V ;  i ++ )              for   ( int  j  =  i + 1 ;  j  <  V ;  j ++ )                  G . addEdge ( vertices [ j ],  vertices [ i ]);          return  G ;      }      /**      * Returns a random rooted-out DAG on { @code  V} vertices and { @code  E} edges.      * A rooted out-tree is a DAG in which every vertex is reachable from a      * single vertex.      * The DAG returned is not chosen uniformly at random among all such DAGs.      *  @param  V the number of vertices      *  @param  E the number of edges      *  @return  a random rooted-out DAG on { @code  V} vertices and { @code  E} edges      */      public   static   Digraph  rootedOutDAG ( int  V ,   int  E )   {          if   ( E  >
 
(
long
)
 V
*
(
V

1
)
 
/
 
2
)
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<  V - 1 )                  throw   new   IllegalArgumentException ( "Too few edges" );          Digraph  G  =   new   Digraph ( V );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
// fix a topological order

        
int
[]
 vertices 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          // one edge pointing from each vertex, other than the root = vertices[V-1]          for   ( int  v  =   0 ;  v  <  V - 1 ;  v ++ )   {              int  w  =   StdRandom . uniform ( v + 1 ,  V );              Edge  e  =   new   Edge ( w ,  v );             set . add ( e );             G . addEdge ( vertices [ w ],  vertices [ v ]);          }          while   ( G . E ()   <  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( w ,  v );              if   (( v  <  w )   &&   ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( vertices [ w ],  vertices [ v ]);              }          }          return  G ;      }      /**      * Returns a random rooted-in tree on { @code  V} vertices.      * A rooted in-tree is an oriented tree in which there is a single vertex      * reachable from every other vertex.      * The tree returned is not chosen uniformly at random among all such trees.      *  @param  V the number of vertices      *  @return  a random rooted-in tree on { @code  V} vertices      */      public   static   Digraph  rootedInTree ( int  V )   {          return  rootedInDAG ( V ,  V - 1 );      }      /**      * Returns a random rooted-out tree on { @code  V} vertices. A rooted out-tree      * is an oriented tree in which each vertex is reachable from a single vertex.      * It is also known as a arborescence or branching.

     * The tree returned is not chosen uniformly at random among all such trees.

     * 
@param
 V the number of vertices

     * 
@return
 a random rooted-out tree on {
@code
 V} vertices

     */

    
public
 
static
 
Digraph
 rootedOutTree
(
int
 V
)
 
{

        
return
 rootedOutDAG
(
V
,
 V

1
);

    
}

    
/**

     * Returns a path digraph on {
@code
 V} vertices.

     * 
@param
 V the number of vertices in the path

     * 
@return
 a digraph that is a directed path on {
@code
 V} vertices

     */

    
public
 
static
 
Digraph
 path
(
int
 V
)
 
{

        
Digraph
 G 
=
 
new
 
Digraph
(
V
);

        
int
[]
 vertices 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }          return  G ;      }      /**      * Returns a complete binary tree digraph on { @code  V} vertices.      *  @param  V the number of vertices in the binary tree      *  @return  a digraph that is a complete binary tree on { @code  V} vertices      */      public   static   Digraph  binaryTree ( int  V )   {          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [( i - 1 ) / 2 ]);          }          return  G ;      }      /**      * Returns a cycle digraph on { @code  V} vertices.      *  @param  V the number of vertices in the cycle      *  @return  a digraph that is a directed cycle on { @code  V} vertices      */      public   static   Digraph  cycle ( int  V )   {          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }         G . addEdge ( vertices [ V - 1 ],  vertices [ 0 ]);          return  G ;      }      /**      * Returns an Eulerian cycle digraph on { @code  V} vertices.      *      *  @param   V the number of vertices in the cycle      *  @param   E the number of edges in the cycle      *  @return  a digraph that is a directed Eulerian cycle on { @code  V} vertices      *         and { @code  E} edges      *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E <= 0}      */      public   static   Digraph  eulerianCycle ( int  V ,   int  E )   {          if   ( E  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one edge" );          if   ( V  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one vertex" );          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ E ];          for   ( int  i  =   0 ;  i  <  E ;  i ++ )             vertices [ i ]   =   StdRandom . uniform ( V );          for   ( int  i  =   0 ;  i  <  E - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }         G . addEdge ( vertices [ E - 1 ],  vertices [ 0 ]);          return  G ;      }      /**      * Returns an Eulerian path digraph on { @code  V} vertices.      *      *  @param   V the number of vertices in the path      *  @param   E the number of edges in the path      *  @return  a digraph that is a directed Eulerian path on { @code  V} vertices      *         and { @code  E} edges      *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E < 0}      */      public   static   Digraph  eulerianPath ( int  V ,   int  E )   {          if   ( E  <   0 )              throw   new   IllegalArgumentException ( "negative number of edges" );          if   ( V  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian path must have at least one vertex" );          Digraph  G  =   new   Digraph ( V );          int []  vertices  =   new   int [ E + 1 ];          for   ( int  i  =   0 ;  i  <  E + 1 ;  i ++ )             vertices [ i ]   =   StdRandom . uniform ( V );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }          return  G ;      }     /**      * Returns a random simple digraph on { @code  V} vertices, { @code  E}      * edges and (at least) { @code  c} strong components. The vertices are randomly      * assigned integer labels between { @code  0} and { @code  c-1} (corresponding to       * strong components). Then, a strong component is creates among the vertices      * with the same label. Next, random edges (either between two vertices with      * the same labels or from a vetex with a smaller label to a vertex with a       * larger label). The number of components will be equal to the number of      * distinct labels that are assigned to vertices.      *      *  @param  V the number of vertices      *  @param  E the number of edges      *  @param  c the (maximum) number of strong components      *  @return  a random simple digraph on { @code  V} vertices and                { @code  E} edges, with (at most) { @code  c} strong components      *  @throws  IllegalArgumentException if { @code  c} is larger than { @code  V}      */      public   static   Digraph  strong ( int  V ,   int  E ,   int  c )   {          if   ( c  >=
 V 
||
 c 
<=   0 )              throw   new   IllegalArgumentException ( "Number of components must be between 1 and V" );          if   ( E  <=   2 * ( V - c ))              throw   new   IllegalArgumentException ( "Number of edges must be at least 2(V-c)" );          if   ( E  >
 
(
long
)
 V
*
(
V

1
)
 
/
 
2
)

            
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
// the digraph

        
Digraph
 G 
=
 
new
 
Digraph
(
V
);

        
// edges added to G (to avoid duplicate edges)

        SET
< Edge >
 set 
=
 
new
 SET
< Edge >
();

        
int
[]
 label 
=
 
new
 
int
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             label [ v ]   =   StdRandom . uniform ( c );          // make all vertices with label c a strong component by          // combining a rooted in-tree and a rooted out-tree          for   ( int  i  =   0 ;  i  <  c ;  i ++ )   {              // how many vertices in component c              int  count  =   0 ;              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  if   ( label [ v ]   ==  i )  count ++ ;              }              // if (count == 0) System.err.println("less than desired number of strong components");              int []  vertices  =   new   int [ count ];              int  j  =   0 ;              for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {                  if   ( label [ v ]   ==  i )  vertices [ j ++ ]   =  v ;              }              StdRandom . shuffle ( vertices );              // rooted-in tree with root = vertices[count-1]              for   ( int  v  =   0 ;  v  <  count - 1 ;  v ++ )   {                  int  w  =   StdRandom . uniform ( v + 1 ,  count );                  Edge  e  =   new   Edge ( w ,  v );                 set . add ( e );                 G . addEdge ( vertices [ w ],  vertices [ v ]);              }              // rooted-out tree with root = vertices[count-1]              for   ( int  v  =   0 ;  v  <  count - 1 ;  v ++ )   {                  int  w  =   StdRandom . uniform ( v + 1 ,  count );                  Edge  e  =   new   Edge ( v ,  w );                 set . add ( e );                 G . addEdge ( vertices [ v ],  vertices [ w ]);              }          }          while   ( G . E ()   <  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( v ,  w );              if   ( ! set . contains ( e )   &&  v  !=  w  &&  label [ v ]   <=  label [ w ])   {                 set . add ( e );                 G . addEdge ( v ,  w );              }          }          return  G ;      }      /**      * Unit tests the { @code  DigraphGenerator} library.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  V  =   Integer . parseInt ( args [ 0 ]);          int  E  =   Integer . parseInt ( args [ 1 ]);          StdOut . println ( "complete graph" );          StdOut . println ( complete ( V ));          StdOut . println ();          StdOut . println ( "simple" );          StdOut . println ( simple ( V ,  E ));          StdOut . println ();          StdOut . println ( "path" );          StdOut . println ( path ( V ));          StdOut . println ();          StdOut . println ( "cycle" );          StdOut . println ( cycle ( V ));          StdOut . println ();          StdOut . println ( "Eulierian path" );          StdOut . println ( eulerianPath ( V ,  E ));          StdOut . println ();          StdOut . println ( "Eulierian cycle" );          StdOut . println ( eulerianCycle ( V ,  E ));          StdOut . println ();          StdOut . println ( "binary tree" );          StdOut . println ( binaryTree ( V ));          StdOut . println ();          StdOut . println ( "tournament" );          StdOut . println ( tournament ( V ));          StdOut . println ();          StdOut . println ( "DAG" );          StdOut . println ( dag ( V ,  E ));          StdOut . println ();          StdOut . println ( "rooted-in DAG" );          StdOut . println ( rootedInDAG ( V ,  E ));          StdOut . println ();          StdOut . println ( "rooted-out DAG" );          StdOut . println ( rootedOutDAG ( V ,  E ));          StdOut . println ();          StdOut . println ( "rooted-in tree" );          StdOut . println ( rootedInTree ( V ));          StdOut . println ();          StdOut . println ( "rooted-out DAG" );          StdOut . println ( rootedOutTree ( V ));          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Digraph.java edu/princeton/cs/algs4/Digraph.java /******************************************************************************  *  Compilation:  javac Digraph.java  *  Execution:    java Digraph filename.txt  *  Dependencies: Bag.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt  *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt    *  *  A graph, implemented using an array of lists.  *  Parallel edges and self-loops are permitted.  *  *  % java Digraph tinyDG.txt  *  13 vertices, 22 edges  *  0: 5 1   *  1:   *  2: 0 3   *  3: 5 2   *  4: 3 2   *  5: 4   *  6: 9 4 8 0   *  7: 6 9  *  8: 6   *  9: 11 10   *  10: 12   *  11: 4 12   *  12: 9   *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  Digraph} class represents a directed graph of vertices  *  named 0 through V – 1.

 *  It supports the following two primary operations: add an edge to the digraph,

 *  iterate over all of the vertices adjacent from a given vertex.

 *  It also provides

 *  methods for returning the indegree or outdegree of a vertex, 

 *  the number of vertices V in the digraph, 

 *  the number of edges E in the digraph, and the reverse digraph.

 *  Parallel edges and self-loops are permitted.

 *  

 *  This implementation uses an adjacency-lists representation, which

 *  is a vertex-indexed array of {
@link
 Bag} objects.

 *  It uses Θ(E + V) space, where E is

 *  the number of edges and V is the number of vertices.

 *  All instance methods take Θ(1) time. (Though, iterating over

 *  the vertices returned by {
@link
 #adj(int)} takes time proportional

 *  to the outdegree of the vertex.)

 *  Constructing an empty digraph with V vertices takes

 *  Θ(V) time; constructing a digraph with E edges

 *  and V vertices takes Θ(E + V) time.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Digraph
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;
           
// number of vertices in this digraph

    
private
 
int
 E
;
                 
// number of edges in this digraph

    
private
 
Bag
< Integer >
[]
 adj
;
    
// adj[v] = adjacency list for vertex v

    
private
 
int
[]
 indegree
;
        
// indegree[v] = indegree of vertex v

    

    
/**

     * Initializes an empty digraph with V vertices.

     *

     * 
@param
  V the number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   Digraph ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;         indegree  =   new   int [ V ];         adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             adj [ v ]   =   new   Bag < Integer >
();

        
}

    
}

    
/**  

     * Initializes a digraph from the specified input stream.

     * The format is the number of vertices V,

     * followed by the number of edges E,

     * followed by E pairs of vertices, with each entry separated by whitespace.

     *

     * 
@param
  in the input stream

     * 
@throws
 IllegalArgumentException if {
@code
 in} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if the endpoints of any edge are not in prescribed range

     * 
@throws
 IllegalArgumentException if the number of vertices or edges is negative

     * 
@throws
 IllegalArgumentException if the input stream is in the wrong format

     */

    
public
 
Digraph
(
In
 in
)
 
{

        
if
 
(
in 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            
this
.

=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Digraph must be nonnegative" );             indegree  =   new   int [ V ];             adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

            
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {                 adj [ v ]   =   new   Bag < Integer >
();

            
}

            
int
 E 
=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of edges in a Digraph must be nonnegative" );              for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {                  int  v  =  in . readInt ();                  int  w  =  in . readInt ();                 addEdge ( v ,  w );                }          }          catch   ( NoSuchElementException  e )   {              throw   new   IllegalArgumentException ( "invalid input format in Digraph constructor" ,  e );          }      }      /**      * Initializes a new digraph that is a deep copy of the specified digraph.      *      *  @param   G the digraph to copy      *  @throws  IllegalArgumentException if { @code  G} is { @code  null}      */      public   Digraph ( Digraph  G )   {          if   ( G  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );          this . V  =  G . V ();          this . E  =  G . E ();          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );          // update indegrees         indegree  =   new   int [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              this . indegree [ v ]   =  G . indegree ( v );          // update adjacency lists         adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             adj [ v ]   =   new   Bag < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              // reverse so that adjacency list is in same order as original              Stack < Integer >
 reverse 
=
 
new
 
Stack
< Integer >
();

            
for
 
(
int
 w 
:
 G
.
adj
[
v
])
 
{

                reverse
.
push
(
w
);

            
}

            
for
 
(
int
 w 
:
 reverse
)
 
{

                adj
[
v
].
add
(
w
);

            
}

        
}

    
}

        

    
/**

     * Returns the number of vertices in this digraph.

     *

     * 
@return
 the number of vertices in this digraph

     */

    
public
 
int
 V
()
 
{

        
return
 V
;

    
}

    
/**

     * Returns the number of edges in this digraph.

     *

     * 
@return
 the number of edges in this digraph

     */

    
public
 
int
 E
()
 
{

        
return
 E
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Adds the directed edge v→w to this digraph.

     *

     * 
@param
  v the tail vertex

     * 
@param
  w the head vertex

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= v < V} and { @code  0 <= w < V}      */      public   void  addEdge ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );         adj [ v ]. add ( w );         indegree [ w ] ++ ;         E ++ ;      }      /**      * Returns the vertices adjacent from vertex { @code  v} in this digraph.      *      *  @param   v the vertex      *  @return  the vertices adjacent from vertex { @code  v} in this digraph, as an iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 adj
[
v
];

    
}

    
/**

     * Returns the number of directed edges incident from vertex {
@code
 v}.

     * This is known as the outdegree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the outdegree of vertex {
@code
 v}               

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  outdegree ( int  v )   {         validateVertex ( v );          return  adj [ v ]. size ();      }      /**      * Returns the number of directed edges incident to vertex { @code  v}.      * This is known as the indegree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the indegree of vertex {
@code
 v}               

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  indegree ( int  v )   {         validateVertex ( v );          return  indegree [ v ];      }      /**      * Returns the reverse of the digraph.      *      *  @return  the reverse of the digraph      */      public   Digraph  reverse ()   {          Digraph  reverse  =   new   Digraph ( V );          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              for   ( int  w  :  adj ( v ))   {                 reverse . addEdge ( w ,  v );              }          }          return  reverse ;      }      /**      * Returns a string representation of the graph.      *      *  @return  the number of vertices V, followed by the number of edges E,  

     *         followed by the V adjacency lists

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” vertices, ”
 
+
 E 
+
 
” edges ”
 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( String . format ( "%d: " ,  v ));              for   ( int  w  :  adj [ v ])   {                 s . append ( String . format ( "%d " ,  w ));              }             s . append ( NEWLINE );          }          return  s . toString ();      }      /**      * Unit tests the { @code  Digraph} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          Digraph  G  =   new   Digraph ( in );          StdOut . println ( G );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DijkstraAllPairsSP.java edu/princeton/cs/algs4/DijkstraAllPairsSP.java /******************************************************************************  *  Compilation:  javac DijkstraAllPairsSP.java  *  Execution:    none  *  Dependencies: EdgeWeightedDigraph.java Dijkstra.java  *  *  Dijkstra's algorithm run from each vertex.   *  Takes time proportional to E V log V and space proportional to EV.  *  *  % java DijkstraAllPairsSP tinyEWD.txt  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DijkstraAllPairsSP} class represents a data type for solving the  *  all-pairs shortest paths problem in edge-weighted digraphs  *  where the edge weights are nonnegative.  *  

 *  This implementation runs Dijkstra’s algorithm from each vertex.

 *  The constructor takes Θ(V (E log V)) time

 *  in the worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V2) extra space (not including the

 *  edge-weighted digraph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DijkstraAllPairsSP
 
{

    
private
 
DijkstraSP
[]
 all
;

    
/**

     * Computes a shortest paths tree from each vertex to to every other vertex in

     * the edge-weighted digraph {
@code
 G}.

     * 
@param
 G the edge-weighted digraph

     * 
@throws
 IllegalArgumentException if an edge weight is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DijkstraAllPairsSP ( EdgeWeightedDigraph  G )   {         all   =   new   DijkstraSP [ G . V ()];          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             all [ v ]   =   new   DijkstraSP ( G ,  v );      }      /**      * Returns a shortest path from vertex { @code  s} to vertex { @code  t}.      *  @param   s the source vertex      *  @param   t the destination vertex      *  @return  a shortest path from vertex { @code  s} to vertex { @code  t}      *         as an iterable of edges, and { @code  null} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= s < V}      *  @throws  IllegalArgumentException unless { @code  0 <= t < V}      */      public   Iterable < DirectedEdge >
 path
(
int
 s
,
 
int
 t
)
 
{

        validateVertex
(
s
);

        validateVertex
(
t
);

        
return
 all
[
s
].
pathTo
(
t
);

    
}

    
/**

     * Is there a path from the vertex {
@code
 s} to vertex {
@code
 t}?

     * 
@param
  s the source vertex

     * 
@param
  t the destination vertex

     * 
@return
 {
@code
 true} if there is a path from vertex {
@code
 s} 

     *         to vertex {
@code
 t}, and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      *  @throws  IllegalArgumentException unless { @code  0 <= t < V}      */      public   boolean  hasPath ( int  s ,   int  t )   {         validateVertex ( s );         validateVertex ( t );          return  dist ( s ,  t )   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns the length of a shortest path from vertex { @code  s} to vertex { @code  t}.      *  @param   s the source vertex      *  @param   t the destination vertex      *  @return  the length of a shortest path from vertex { @code  s} to vertex { @code  t};      *         { @code  Double.POSITIVE_INFINITY} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= s < V}      *  @throws  IllegalArgumentException unless { @code  0 <= t < V}      */      public   double  dist ( int  s ,   int  t )   {         validateVertex ( s );         validateVertex ( t );          return  all [ s ]. distTo ( t );      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  all . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DijkstraAllPairsSP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// read edge-weighted digraph

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
in
);

        
// compute shortest paths between all pairs of vertices

        
DijkstraAllPairsSP
 spt 
=
 
new
 
DijkstraAllPairsSP
(
G
);

        
// print all-pairs shortest path distances

        
StdOut
.
printf
(
”  ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              StdOut . printf ( "%6d " ,  v );          }          StdOut . println ();          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              StdOut . printf ( "%3d: " ,  v );              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( spt . hasPath ( v ,  w ))   StdOut . printf ( "%6.2f " ,  spt . dist ( v ,  w ));                  else   StdOut . printf ( "  Inf " );              }              StdOut . println ();          }          StdOut . println ();          // print all-pairs shortest paths          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( spt . hasPath ( v ,  w ))   {                      StdOut . printf ( "%d to %d (%5.2f)  " ,  v ,  w ,  spt . dist ( v ,  w ));                      for   ( DirectedEdge  e  :  spt . path ( v ,  w ))                          StdOut . print ( e  +   "  " );                      StdOut . println ();                  }                  else   {                      StdOut . printf ( "%d to %d no path\n" ,  v ,  w );                  }              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DijkstraSP.java edu/princeton/cs/algs4/DijkstraSP.java /******************************************************************************  *  Compilation:  javac DijkstraSP.java  *  Execution:    java DijkstraSP input.txt s  *  Dependencies: EdgeWeightedDigraph.java IndexMinPQ.java Stack.java DirectedEdge.java  *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWD.txt  *                https://algs4.cs.princeton.edu/44sp/mediumEWD.txt  *                https://algs4.cs.princeton.edu/44sp/largeEWD.txt  *  *  Dijkstra's algorithm. Computes the shortest path tree.  *  Assumes all weights are nonnegative.  *  *  % java DijkstraSP tinyEWD.txt 0  *  0 to 0 (0.00)    *  0 to 1 (1.05)  0->4  0.38   4->5  0.35   5->1  0.32   

 *  0 to 2 (0.26)  0->2  0.26   

 *  0 to 3 (0.99)  0->2  0.26   2->7  0.34   7->3  0.39   

 *  0 to 4 (0.38)  0->4  0.38   

 *  0 to 5 (0.73)  0->4  0.38   4->5  0.35   

 *  0 to 6 (1.51)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   

 *  0 to 7 (0.60)  0->2  0.26   2->7  0.34   

 *

 *  % java DijkstraSP mediumEWD.txt 0

 *  0 to 0 (0.00)  

 *  0 to 1 (0.71)  0->44  0.06   44->93  0.07   …  107->1  0.07   

 *  0 to 2 (0.65)  0->44  0.06   44->231  0.10  …  42->2  0.11   

 *  0 to 3 (0.46)  0->97  0.08   97->248  0.09  …  45->3  0.12   

 *  0 to 4 (0.42)  0->44  0.06   44->93  0.07   …  77->4  0.11   

 *  …

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 DijkstraSP} class represents a data type for solving the

 *  single-source shortest paths problem in edge-weighted digraphs

 *  where the edge weights are nonnegative.

 *  

 *  This implementation uses Dijkstra’s algorithm with a

 *  binary heap. The constructor takes

 *  Θ(E log V) time in the worst case,

 *  where V is the number of vertices and E is

 *  the number of edges. Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted digraph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DijkstraSP
 
{

    
private
 
double
[]
 distTo
;
          
// distTo[v] = distance  of shortest s->v path

    
private
 
DirectedEdge
[]
 edgeTo
;
    
// edgeTo[v] = last edge on shortest s->v path

    
private
 
IndexMinPQ
< Double >
 pq
;
    
// priority queue of vertices

    
/**

     * Computes a shortest-paths tree from the source vertex {
@code
 s} to every other

     * vertex in the edge-weighted digraph {
@code
 G}.

     *

     * 
@param
  G the edge-weighted digraph

     * 
@param
  s the source vertex

     * 
@throws
 IllegalArgumentException if an edge weight is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DijkstraSP ( EdgeWeightedDigraph  G ,   int  s )   {          for   ( DirectedEdge  e  :  G . edges ())   {              if   ( e . weight ()   <   0 )                  throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );          }         distTo  =   new   double [ G . V ()];         edgeTo  =   new   DirectedEdge [ G . V ()];         validateVertex ( s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =   Double . POSITIVE_INFINITY ;         distTo [ s ]   =   0.0 ;          // relax vertices in order of distance from s         pq  =   new   IndexMinPQ < Double >
(
G
.
V
());

        pq
.
insert
(
s
,
 distTo
[
s
]);

        
while
 
(
!
pq
.
isEmpty
())
 
{

            
int
 v 
=
 pq
.
delMin
();

            
for
 
(
DirectedEdge
 e 
:
 G
.
adj
(
v
))

                relax
(
e
);

        
}

        
// check optimality conditions

        
assert
 check
(
G
,
 s
);

    
}

    
// relax edge e and update pq if changed

    
private
 
void
 relax
(
DirectedEdge
 e
)
 
{

        
int
 v 
=
 e
.
from
(),
 w 
=
 e
.
to
();

        
if
 
(
distTo
[
w
]
 
>
 distTo
[
v
]
 
+
 e
.
weight
())
 
{

            distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 e
.
weight
();

            edgeTo
[
w
]
 
=
 e
;

            
if
 
(
pq
.
contains
(
w
))
 pq
.
decreaseKey
(
w
,
 distTo
[
w
]);

            
else
                pq
.
insert
(
w
,
 distTo
[
w
]);

        
}

    
}

    
/**

     * Returns the length of a shortest path from the source vertex {
@code
 s} to vertex {
@code
 v}.

     * 
@param
  v the destination vertex

     * 
@return
 the length of a shortest path from the source vertex {
@code
 s} to vertex {
@code
 v};

     *         {
@code
 Double.POSITIVE_INFINITY} if no such path

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   double  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Returns true if there is a path from the source vertex { @code  s} to vertex { @code  v}.      *      *  @param   v the destination vertex      *  @return  { @code  true} if there is a path from the source vertex      *         { @code  s} to vertex { @code  v}; { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns a shortest path from the source vertex { @code  s} to vertex { @code  v}.      *      *  @param   v the destination vertex      *  @return  a shortest path from the source vertex { @code  s} to vertex { @code  v}      *         as an iterable of edges, and { @code  null} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < DirectedEdge >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< DirectedEdge >
 path 
=
 
new
 
Stack
< DirectedEdge >
();

        
for
 
(
DirectedEdge
 e 
=
 edgeTo
[
v
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
e
.
from
()])
 
{

            path
.
push
(
e
);

        
}

        
return
 path
;

    
}

    
// check optimality conditions:

    
// (i) for all edges e:            distTo[e.to()] <= distTo[e.from()] + e.weight()      // (ii) for all edge e on the SPT: distTo[e.to()] == distTo[e.from()] + e.weight()      private   boolean  check ( EdgeWeightedDigraph  G ,   int  s )   {          // check that edge weights are nonnegative          for   ( DirectedEdge  e  :  G . edges ())   {              if   ( e . weight ()   <   0 )   {                  System . err . println ( "negative edge weight detected" );                  return   false ;              }          }          // check that distTo[v] and edgeTo[v] are consistent          if   ( distTo [ s ]   !=   0.0   ||  edgeTo [ s ]   !=   null )   {              System . err . println ( "distTo[s] and edgeTo[s] inconsistent" );              return   false ;          }          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              if   ( v  ==  s )   continue ;              if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {                  System . err . println ( "distTo[] and edgeTo[] inconsistent" );                  return   false ;              }          }          // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( DirectedEdge  e  :  G . adj ( v ))   {                  int  w  =  e . to ();                  if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {                      System . err . println ( "edge "   +  e  +   " not relaxed" );                      return   false ;                  }              }          }          // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()

        
for
 
(
int
 w 
=
 
0
;
 w 
<  G . V ();  w ++ )   {              if   ( edgeTo [ w ]   ==   null )   continue ;              DirectedEdge  e  =  edgeTo [ w ];              int  v  =  e . from ();              if   ( w  !=  e . to ())   return   false ;              if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {                  System . err . println ( "edge "   +  e  +   " on shortest path not tight" );                  return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DijkstraSP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// compute shortest paths

        
DijkstraSP
 sp 
=
 
new
 
DijkstraSP
(
G
,
 s
);

        
// print shortest path

        
for
 
(
int
 t 
=
 
0
;
 t 
<  G . V ();  t ++ )   {              if   ( sp . hasPathTo ( t ))   {                  StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  t ,  sp . distTo ( t ));                  for   ( DirectedEdge  e  :  sp . pathTo ( t ))   {                      StdOut . print ( e  +   "   " );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d         no path\n" ,  s ,  t );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DijkstraUndirectedSP.java edu/princeton/cs/algs4/DijkstraUndirectedSP.java /******************************************************************************  *  Compilation:  javac DijkstraUndirectedSP.java  *  Execution:    java DijkstraUndirectedSP input.txt s  *  Dependencies: EdgeWeightedGraph.java IndexMinPQ.java Stack.java Edge.java  *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt  *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt  *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt  *  *  Dijkstra's algorithm. Computes the shortest path tree.  *  Assumes all weights are nonnegative.  *  *  % java DijkstraUndirectedSP tinyEWG.txt 6  *  6 to 0 (0.58)  6-0 0.58000  *  6 to 1 (0.76)  6-2 0.40000   1-2 0.36000  *  6 to 2 (0.40)  6-2 0.40000  *  6 to 3 (0.52)  3-6 0.52000  *  6 to 4 (0.93)  6-4 0.93000  *  6 to 5 (1.02)  6-2 0.40000   2-7 0.34000   5-7 0.28000  *  6 to 6 (0.00)  *  6 to 7 (0.74)  6-2 0.40000   2-7 0.34000  *  *  % java DijkstraUndirectedSP mediumEWG.txt 0  *  0 to 0 (0.00)  *  0 to 1 (0.71)  0-44 0.06471   44-93  0.06793  ...   1-107 0.07484  *  0 to 2 (0.65)  0-44 0.06471   44-231 0.10384  ...   2-42  0.11456  *  0 to 3 (0.46)  0-97 0.07705   97-248 0.08598  ...   3-45  0.11902  *  ...  *  *  % java DijkstraUndirectedSP largeEWG.txt 0  *  0 to 0 (0.00)    *  0 to 1 (0.78)  0-460790 0.00190  460790-696678 0.00173   ...   1-826350 0.00191  *  0 to 2 (0.61)  0-15786  0.00130  15786-53370   0.00113   ...   2-793420 0.00040  *  0 to 3 (0.31)  0-460790 0.00190  460790-752483 0.00194   ...   3-698373 0.00172  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DijkstraUndirectedSP} class represents a data type for solving  *  the single-source shortest paths problem in edge-weighted graphs  *  where the edge weights are nonnegative.  *  

 *  This implementation uses Dijkstra’s algorithm with a binary heap.

 *  The constructor takes Θ(E log V) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the

 *  edge-weighted graph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *  See {
@link
 DijkstraSP} for a version on edge-weighted digraphs.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 Nate Liu

 */

public
 
class
 
DijkstraUndirectedSP
 
{

    
private
 
double
[]
 distTo
;
          
// distTo[v] = distance  of shortest s->v path

    
private
 
Edge
[]
 edgeTo
;
            
// edgeTo[v] = last edge on shortest s->v path

    
private
 
IndexMinPQ
< Double >
 pq
;
    
// priority queue of vertices

    
/**

     * Computes a shortest-paths tree from the source vertex {
@code
 s} to every

     * other vertex in the edge-weighted graph {
@code
 G}.

     *

     * 
@param
  G the edge-weighted digraph

     * 
@param
  s the source vertex

     * 
@throws
 IllegalArgumentException if an edge weight is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DijkstraUndirectedSP ( EdgeWeightedGraph  G ,   int  s )   {          for   ( Edge  e  :  G . edges ())   {              if   ( e . weight ()   <   0 )                  throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );          }         distTo  =   new   double [ G . V ()];         edgeTo  =   new   Edge [ G . V ()];         validateVertex ( s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )             distTo [ v ]   =   Double . POSITIVE_INFINITY ;         distTo [ s ]   =   0.0 ;          // relax vertices in order of distance from s         pq  =   new   IndexMinPQ < Double >
(
G
.
V
());

        pq
.
insert
(
s
,
 distTo
[
s
]);

        
while
 
(
!
pq
.
isEmpty
())
 
{

            
int
 v 
=
 pq
.
delMin
();

            
for
 
(
Edge
 e 
:
 G
.
adj
(
v
))

                relax
(
e
,
 v
);

        
}

        
// check optimality conditions

        
assert
 check
(
G
,
 s
);

    
}

    
// relax edge e and update pq if changed

    
private
 
void
 relax
(
Edge
 e
,
 
int
 v
)
 
{

        
int
 w 
=
 e
.
other
(
v
);

        
if
 
(
distTo
[
w
]
 
>
 distTo
[
v
]
 
+
 e
.
weight
())
 
{

            distTo
[
w
]
 
=
 distTo
[
v
]
 
+
 e
.
weight
();

            edgeTo
[
w
]
 
=
 e
;

            
if
 
(
pq
.
contains
(
w
))
 pq
.
decreaseKey
(
w
,
 distTo
[
w
]);

            
else
                pq
.
insert
(
w
,
 distTo
[
w
]);

        
}

    
}

    
/**

     * Returns the length of a shortest path between the source vertex {
@code
 s} and

     * vertex {
@code
 v}.

     *

     * 
@param
  v the destination vertex

     * 
@return
 the length of a shortest path between the source vertex {
@code
 s} and

     *         the vertex {
@code
 v}; {
@code
 Double.POSITIVE_INFINITY} if no such path

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   double  distTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ];      }      /**      * Returns true if there is a path between the source vertex { @code  s} and      * vertex { @code  v}.      *      *  @param   v the destination vertex      *  @return  { @code  true} if there is a path between the source vertex      *         { @code  s} to vertex { @code  v}; { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  hasPathTo ( int  v )   {         validateVertex ( v );          return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns a shortest path between the source vertex { @code  s} and vertex { @code  v}.      *      *  @param   v the destination vertex      *  @return  a shortest path between the source vertex { @code  s} and vertex { @code  v};      *         { @code  null} if no such path      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Edge >
 pathTo
(
int
 v
)
 
{

        validateVertex
(
v
);

        
if
 
(
!
hasPathTo
(
v
))
 
return
 
null
;

        
Stack
< Edge >
 path 
=
 
new
 
Stack
< Edge >
();

        
int
 x 
=
 v
;

        
for
 
(
Edge
 e 
=
 edgeTo
[
v
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
x
])
 
{

            path
.
push
(
e
);

            x 
=
 e
.
other
(
x
);

        
}

        
return
 path
;

    
}

    
// check optimality conditions:

    
// (i) for all edges e = v-w:            distTo[w] <= distTo[v] + e.weight()      // (ii) for all edge e = v-w on the SPT: distTo[w] == distTo[v] + e.weight()      private   boolean  check ( EdgeWeightedGraph  G ,   int  s )   {          // check that edge weights are nonnegative          for   ( Edge  e  :  G . edges ())   {              if   ( e . weight ()   <   0 )   {                  System . err . println ( "negative edge weight detected" );                  return   false ;              }          }          // check that distTo[v] and edgeTo[v] are consistent          if   ( distTo [ s ]   !=   0.0   ||  edgeTo [ s ]   !=   null )   {              System . err . println ( "distTo[s] and edgeTo[s] inconsistent" );              return   false ;          }          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              if   ( v  ==  s )   continue ;              if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {                  System . err . println ( "distTo[] and edgeTo[] inconsistent" );                  return   false ;              }          }          // check that all edges e = v-w satisfy distTo[w] <= distTo[v] + e.weight()          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( Edge  e  :  G . adj ( v ))   {                  int  w  =  e . other ( v );                  if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {                      System . err . println ( "edge "   +  e  +   " not relaxed" );                      return   false ;                  }              }          }          // check that all edges e = v-w on SPT satisfy distTo[w] == distTo[v] + e.weight()          for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {              if   ( edgeTo [ w ]   ==   null )   continue ;              Edge  e  =  edgeTo [ w ];              if   ( w  !=  e . either ()   &&  w  !=  e . other ( e . either ()))   return   false ;              int  v  =  e . other ( w );              if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {                  System . err . println ( "edge "   +  e  +   " on shortest path not tight" );                  return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 DijkstraUndirectedSP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
EdgeWeightedGraph
 G 
=
 
new
 
EdgeWeightedGraph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// compute shortest paths

        
DijkstraUndirectedSP
 sp 
=
 
new
 
DijkstraUndirectedSP
(
G
,
 s
);

        
// print shortest path

        
for
 
(
int
 t 
=
 
0
;
 t 
<  G . V ();  t ++ )   {              if   ( sp . hasPathTo ( t ))   {                  StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  t ,  sp . distTo ( t ));                  for   ( Edge  e  :  sp . pathTo ( t ))   {                      StdOut . print ( e  +   "   " );                  }                  StdOut . println ();              }              else   {                  StdOut . printf ( "%d to %d         no path\n" ,  s ,  t );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DirectedCycle.java edu/princeton/cs/algs4/DirectedCycle.java /******************************************************************************  *  Compilation:  javac DirectedCycle.java  *  Execution:    java DirectedCycle input.txt  *  Dependencies: Digraph.java Stack.java StdOut.java In.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt  *  *  Finds a directed cycle in a digraph.  *  *  % java DirectedCycle tinyDG.txt   *  Directed cycle: 3 5 4 3   *  *  %  java DirectedCycle tinyDAG.txt   *  No directed cycle  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DirectedCycle} class represents a data type for   *  determining whether a digraph has a directed cycle.  *  The hasCycle operation determines whether the digraph has

 *  a simple directed cycle and, if so, the cycle operation

 *  returns one.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the worst

 *  case, where V is the number of vertices and E is

 *  the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  See {
@link
 Topological} to compute a topological order if the

 *  digraph is acyclic.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DirectedCycle
 
{

    
private
 
boolean
[]
 marked
;
        
// marked[v] = has vertex v been marked?

    
private
 
int
[]
 edgeTo
;
            
// edgeTo[v] = previous vertex on path to v

    
private
 
boolean
[]
 onStack
;
       
// onStack[v] = is vertex on the stack?

    
private
 
Stack
< Integer >
 cycle
;
    
// directed cycle (or null if no such cycle)

    
/**

     * Determines whether the digraph {
@code
 G} has a directed cycle and, if so,

     * finds such a cycle.

     * 
@param
 G the digraph

     */

    
public
 
DirectedCycle
(
Digraph
 G
)
 
{

        marked  
=
 
new
 
boolean
[
G
.
V
()];

        onStack 
=
 
new
 
boolean
[
G
.
V
()];

        edgeTo  
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( ! marked [ v ]   &&  cycle  ==   null )  dfs ( G ,  v );      }      // check that algorithm computes either the topological order or finds a directed cycle      private   void  dfs ( Digraph  G ,   int  v )   {         onStack [ v ]   =   true ;         marked [ v ]   =   true ;          for   ( int  w  :  G . adj ( v ))   {              // short circuit if directed cycle found              if   ( cycle  !=   null )   return ;              // found new vertex, so recur              else   if   ( ! marked [ w ])   {                 edgeTo [ w ]   =  v ;                 dfs ( G ,  w );              }              // trace back directed cycle              else   if   ( onStack [ w ])   {                 cycle  =   new   Stack < Integer >
();

                
for
 
(
int
 x 
=
 v
;
 x 
!=
 w
;
 x 
=
 edgeTo
[
x
])
 
{

                    cycle
.
push
(
x
);

                
}

                cycle
.
push
(
w
);

                cycle
.
push
(
v
);

                
assert
 check
();

            
}

        
}

        onStack
[
v
]
 
=
 
false
;

    
}

    
/**

     * Does the digraph have a directed cycle?

     * 
@return
 {
@code
 true} if the digraph has a directed cycle, {
@code
 false} otherwise

     */

    
public
 
boolean
 hasCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
/**

     * Returns a directed cycle if the digraph has a directed cycle, and {
@code
 null} otherwise.

     * 
@return
 a directed cycle (as an iterable) if the digraph has a directed cycle,

     *    and {
@code
 null} otherwise

     */

    
public
 
Iterable
< Integer >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
// certify that digraph has a directed cycle if it reports one

    
private
 
boolean
 check
()
 
{

        
if
 
(
hasCycle
())
 
{

            
// verify cycle

            
int
 first 
=
 

1
,
 last 
=
 

1
;

            
for
 
(
int
 v 
:
 cycle
())
 
{

                
if
 
(
first 
==
 

1
)
 first 
=
 v
;

                last 
=
 v
;

            
}

            
if
 
(
first 
!=
 last
)
 
{

                
System
.
err
.
printf
(
“cycle begins with %d and ends with %d\n”
,
 first
,
 last
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
/**

     * Unit tests the {
@code
 DirectedCycle} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
DirectedCycle
 finder 
=
 
new
 
DirectedCycle
(
G
);

        
if
 
(
finder
.
hasCycle
())
 
{

            
StdOut
.
print
(
“Directed cycle: ”
);

            
for
 
(
int
 v 
:
 finder
.
cycle
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“No directed cycle”
);

        
}

        
StdOut
.
println
();

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/DirectedCycleX.java
edu/princeton/cs/algs4/DirectedCycleX.java
/******************************************************************************

 *  Compilation:  javac DirectedCycleX.java

 *  Execution:    java DirectedCycleX V E F

 *  Dependencies: Queue.java Digraph.java Stack.java

 *

 *  Find a directed cycle in a digraph, using a nonrecursive, queue-based

 *  algorithm. Runs in O(E + V) time.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 DirectedCycleX} class represents a data type for 

 *  determining whether a digraph has a directed cycle.

 *  The hasCycle operation determines whether the digraph has

 *  a simple directed cycle and, if so, the cycle operation

 *  returns one.

 *  

 *  This implementation uses a nonrecursive, queue-based algorithm.

 *  The constructor takes time proportional to V + E

 *  (in the worst case),

 *  where V is the number of vertices and E is the

 *  number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  See {
@link
 DirectedCycle} for a recursive version that uses depth-first search.

 *  See {
@link
 Topological} or {
@link
 TopologicalX} to compute a topological order

 *  when the digraph is acyclic.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DirectedCycleX
 
{

    
private
 
Stack
< Integer >
 cycle
;
     
// the directed cycle; null if digraph is acyclic

    
public
 
DirectedCycleX
(
Digraph
 G
)
 
{

        
// indegrees of remaining vertices

        
int
[]
 indegree 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             indegree [ v ]   =  G . indegree ( v );          }          // initialize queue to contain all vertices with indegree = 0          Queue < Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );          while   ( ! queue . isEmpty ())   {              int  v  =  queue . dequeue ();              for   ( int  w  :  G . adj ( v ))   {                 indegree [ w ] -- ;                  if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );              }          }          // there is a directed cycle in subgraph of vertices with indegree >= 1.

        
int
[]
 edgeTo 
=
 
new
 
int
[
G
.
V
()];

        
int
 root 
=
 

1
;
  
// any vertex with indegree >= -1

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( indegree [ v ]   ==   0 )   continue ;              else  root  =  v ;              for   ( int  w  :  G . adj ( v ))   {                  if   ( indegree [ w ]   >
 
0
)
 
{

                    edgeTo
[
w
]
 
=
 v
;

                
}

            
}

        
}

        
if
 
(
root 
!=
 

1
)
 
{

            
// find any vertex on cycle

            
boolean
[]
 visited 
=
 
new
 
boolean
[
G
.
V
()];

            
while
 
(
!
visited
[
root
])
 
{

                visited
[
root
]
 
=
 
true
;

                root 
=
 edgeTo
[
root
];

            
}

            
// extract cycle

            cycle 
=
 
new
 
Stack
< Integer >
();

            
int
 v 
=
 root
;

            
do
 
{

                cycle
.
push
(
v
);

                v 
=
 edgeTo
[
v
];

            
}
 
while
 
(

!=
 root
);

            cycle
.
push
(
root
);

        
}

        
assert
 check
();

    
}

    
/**

     * Returns a directed cycle if the digraph has a directed cycle, and {
@code
 null} otherwise.

     * 
@return
 a directed cycle (as an iterable) if the digraph has a directed cycle,

     *    and {
@code
 null} otherwise

     */

    
public
 
Iterable
< Integer >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
/**

     * Does the digraph have a directed cycle?

     * 
@return
 {
@code
 true} if the digraph has a directed cycle, {
@code
 false} otherwise

     */

    
public
 
boolean
 hasCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
// certify that digraph has a directed cycle if it reports one

    
private
 
boolean
 check
()
 
{

        
if
 
(
hasCycle
())
 
{

            
// verify cycle

            
int
 first 
=
 

1
,
 last 
=
 

1
;

            
for
 
(
int
 v 
:
 cycle
())
 
{

                
if
 
(
first 
==
 

1
)
 first 
=
 v
;

                last 
=
 v
;

            
}

            
if
 
(
first 
!=
 last
)
 
{

                
System
.
err
.
printf
(
“cycle begins with %d and ends with %d\n”
,
 first
,
 last
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// create random DAG with V vertices and E edges; then add F random edges

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 F 
=
 
Integer
.
parseInt
(
args
[
2
]);

        
Digraph
 G 
=
 
DigraphGenerator
.
dag
(
V
,
 E
);

        
// add F extra edges

        
for
 
(
int
 i 
=
 
0
;
 i 
<  F ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );             G . addEdge ( v ,  w );          }          StdOut . println ( G );          DirectedCycleX  finder  =   new   DirectedCycleX ( G );          if   ( finder . hasCycle ())   {              StdOut . print ( "Directed cycle: " );              for   ( int  v  :  finder . cycle ())   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }          else   {              StdOut . println ( "No directed cycle" );          }          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DirectedDFS.java edu/princeton/cs/algs4/DirectedDFS.java /******************************************************************************  *  Compilation:  javac DirectedDFS.java  *  Execution:    java DirectedDFS digraph.txt s  *  Dependencies: Digraph.java Bag.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt  *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt  *  *  Determine single-source or multiple-source reachability in a digraph  *  using depth first search.  *  Runs in O(E + V) time.  *  *  % java DirectedDFS tinyDG.txt 1  *  1  *  *  % java DirectedDFS tinyDG.txt 2  *  0 1 2 3 4 5  *  *  % java DirectedDFS tinyDG.txt 1 2 6  *  0 1 2 3 4 5 6 8 9 10 11 12   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DirectedDFS} class represents a data type for   *  determining the vertices reachable from a given source vertex s

 *  (or set of source vertices) in a digraph. For versions that find the paths,

 *  see {
@link
 DepthFirstDirectedPaths} and {
@link
 BreadthFirstDirectedPaths}.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes time proportional to V + E

 *  (in the worst case),

 *  where V is the number of vertices and E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DirectedDFS
 
{

    
private
 
boolean
[]
 marked
;
  
// marked[v] = true iff v is reachable from source(s)

    
private
 
int
 count
;
         
// number of vertices reachable from source(s)

    
/**

     * Computes the vertices in digraph {
@code
 G} that are

     * reachable from the source vertex {
@code
 s}.

     * 
@param
 G the digraph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   DirectedDFS ( Digraph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         validateVertex ( s );         dfs ( G ,  s );      }      /**      * Computes the vertices in digraph { @code  G} that are      * connected to any of the source vertices { @code  sources}.      *  @param  G the graph      *  @param  sources the source vertices      *  @throws  IllegalArgumentException unless { @code  0 <= s < V}      *         for each vertex { @code  s} in { @code  sources}      */      public   DirectedDFS ( Digraph  G ,   Iterable < Integer >
 sources
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        validateVertices
(
sources
);

        
for
 
(
int
 v 
:
 sources
)
 
{

            
if
 
(
!
marked
[
v
])
 dfs
(
G
,
 v
);

        
}

    
}

    
private
 
void
 dfs
(
Digraph
 G
,
 
int
 v
)
 
{
 

        count
++
;

        marked
[
v
]
 
=
 
true
;

        
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

            
if
 
(
!
marked
[
w
])
 dfs
(
G
,
 w
);

        
}

    
}

    
/**

     * Is there a directed path from the source vertex (or any

     * of the source vertices) and vertex {
@code
 v}?

     * 
@param
  v the vertex

     * 
@return
 {
@code
 true} if there is a directed path, {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   boolean  marked ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      /**      * Returns the number of vertices reachable from the source vertex      * (or source vertices).      *  @return  the number of vertices reachable from the source vertex      *   (or source vertices)      */      public   int  count ()   {          return  count ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertices ( Iterable < Integer >
 vertices
)
 
{

        
if
 
(
vertices 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
}

        
int
 V 
=
 marked
.
length
;

        
for
 
(
int
 v 
:
 vertices
)
 
{

            
if
 
(

<   0   ||  v  >=
 V
)
 
{

                
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

            
}

        
}

    
}

    
/**

     * Unit tests the {
@code
 DirectedDFS} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// read in digraph from command-line argument

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
// read in sources from command-line arguments

        
Bag
< Integer >
 sources 
=
 
new
 
Bag
< Integer >
();

        
for
 
(
int
 i 
=
 
1
;
 i 
<  args . length ;  i ++ )   {              int  s  =   Integer . parseInt ( args [ i ]);             sources . add ( s );          }          // multiple-source reachability          DirectedDFS  dfs  =   new   DirectedDFS ( G ,  sources );          // print out vertices reachable from sources          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              if   ( dfs . marked ( v ))   StdOut . print ( v  +   " " );          }          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DirectedEdge.java edu/princeton/cs/algs4/DirectedEdge.java /******************************************************************************  *  Compilation:  javac DirectedEdge.java  *  Execution:    java DirectedEdge  *  Dependencies: StdOut.java  *  *  Immutable weighted directed edge.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DirectedEdge} class represents a weighted edge in an   *  { @link  EdgeWeightedDigraph}. Each edge consists of two integers  *  (naming the two vertices) and a real-value weight. The data type  *  provides methods for accessing the two endpoints of the directed edge and  *  the weight.  *  

 *  For additional documentation, see Section 4.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DirectedEdge
 
{
 

    
private
 
final
 
int
 v
;

    
private
 
final
 
int
 w
;

    
private
 
final
 
double
 weight
;

    
/**

     * Initializes a directed edge from vertex {
@code
 v} to vertex {
@code
 w} with

     * the given {
@code
 weight}.

     * 
@param
 v the tail vertex

     * 
@param
 w the head vertex

     * 
@param
 weight the weight of the directed edge

     * 
@throws
 IllegalArgumentException if either {
@code
 v} or {
@code
 w}

     *    is a negative integer

     * 
@throws
 IllegalArgumentException if {
@code
 weight} is {
@code
 NaN}

     */

    
public
 
DirectedEdge
(
int
 v
,
 
int
 w
,
 
double
 weight
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Vertex names must be nonnegative integers" );          if   ( w  <   0 )   throw   new   IllegalArgumentException ( "Vertex names must be nonnegative integers" );          if   ( Double . isNaN ( weight ))   throw   new   IllegalArgumentException ( "Weight is NaN" );          this . v  =  v ;          this . w  =  w ;          this . weight  =  weight ;      }      /**      * Returns the tail vertex of the directed edge.      *  @return  the tail vertex of the directed edge      */      public   int  from ()   {          return  v ;      }      /**      * Returns the head vertex of the directed edge.      *  @return  the head vertex of the directed edge      */      public   int  to ()   {          return  w ;      }      /**      * Returns the weight of the directed edge.      *  @return  the weight of the directed edge      */      public   double  weight ()   {          return  weight ;      }      /**      * Returns a string representation of the directed edge.      *  @return  a string representation of the directed edge      */      public   String  toString ()   {          return  v  +   "->”
 
+
 w 
+
 
” ”
 
+
 
String
.
format
(
“%5.2f”
,
 weight
);

    
}

    
/**

     * Unit tests the {
@code
 DirectedEdge} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
DirectedEdge
 e 
=
 
new
 
DirectedEdge
(
12
,
 
34
,
 
5.67
);

        
StdOut
.
println
(
e
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/DirectedEulerianCycle.java
edu/princeton/cs/algs4/DirectedEulerianCycle.java
/******************************************************************************

 *  Compilation:  javac DirectedEulerianCycle.java

 *  Execution:    java DirectedEulerianCycle V E

 *  Dependencies: Digraph.java Stack.java StdOut.java

 *                BreadthFirstPaths.java

 *                DigraphGenerator.java StdRandom.java

 *

 *  Find an Eulerian cycle in a digraph, if one exists.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

/**

 *  The {
@code
 DirectedEulerianCycle} class represents a data type

 *  for finding an Eulerian cycle or path in a digraph.

 *  An Eulerian cycle is a cycle (not necessarily simple) that

 *  uses every edge in the digraph exactly once.

 *  

 *  This implementation uses a nonrecursive depth-first search.

 *  The constructor takes Θ(E + V) time in the worst

 *  case, where E is the number of edges and V is the

 *  number of vertices

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  To compute Eulerian paths in digraphs, see {
@link
 DirectedEulerianPath}.

 *  To compute Eulerian cycles and paths in undirected graphs, see

 *  {
@link
 EulerianCycle} and {
@link
 EulerianPath}.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 * 

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 Nate Liu

 */

public
 
class
 
DirectedEulerianCycle
 
{

    
private
 
Stack
< Integer >
 cycle 
=
 
null
;
  
// Eulerian cycle; null if no such cylce

    
/**

     * Computes an Eulerian cycle in the specified digraph, if one exists.

     * 

     * 
@param
 G the digraph

     */

    
public
 
DirectedEulerianCycle
(
Digraph
 G
)
 
{

        
// must have at least one edge

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
;

        
// necessary condition: indegree(v) = outdegree(v) for each vertex v

        
// (without this check, DFS might return a path instead of a cycle)

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . outdegree ( v )   !=  G . indegree ( v ))                  return ;          // create local view of adjacency lists, to iterate one vertex at a time          Iterator < Integer >
[]
 adj 
=
 
(
Iterator
< Integer >
[])
 
new
 
Iterator
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =  G . adj ( v ). iterator ();          // initialize stack with any non-isolated vertex          int  s  =  nonIsolatedVertex ( G );          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        stack
.
push
(
s
);

        
// greedily add to putative cycle, depth-first search style

        cycle 
=
 
new
 
Stack
< Integer >
();

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
pop
();

            
while
 
(
adj
[
v
].
hasNext
())
 
{

                stack
.
push
(
v
);

                v 
=
 adj
[
v
].
next
();

            
}

            
// add vertex with no more leaving edges to cycle

            cycle
.
push
(
v
);

        
}

        
// check if all edges have been used

        
// (in case there are two or more vertex-disjoint Eulerian cycles)

        
if
 
(
cycle
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)

            cycle 
=
 
null
;

        
assert
 certifySolution
(
G
);

    
}

    
/**

     * Returns the sequence of vertices on an Eulerian cycle.

     * 

     * 
@return
 the sequence of vertices on an Eulerian cycle;

     *         {
@code
 null} if no such cycle

     */

    
public
 
Iterable
< Integer >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
/**

     * Returns true if the digraph has an Eulerian cycle.

     * 

     * 
@return
 {
@code
 true} if the digraph has an Eulerian cycle;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasEulerianCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
// returns any non-isolated vertex; -1 if no such vertex

    
private
 
static
 
int
 nonIsolatedVertex
(
Digraph
 G
)
 
{

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . outdegree ( v )   >
 
0
)

                
return
 v
;

        
return
 

1
;

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// Determines whether a digraph has an Eulerian cycle using necessary

    
// and sufficient conditions (without computing the cycle itself):

    
//    – at least one edge

    
//    – indegree(v) = outdegree(v) for every vertex

    
//    – the graph is connected, when viewed as an undirected graph

    
//      (ignoring isolated vertices)

    
private
 
static
 
boolean
 satisfiesNecessaryAndSufficientConditions
(
Digraph
 G
)
 
{

        
// Condition 0: at least 1 edge

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
 
false
;

        
// Condition 1: indegree(v) == outdegree(v) for every vertex

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . outdegree ( v )   !=  G . indegree ( v ))                  return   false ;          // Condition 2: graph is connected, ignoring isolated vertices          Graph  H  =   new   Graph ( G . V ());          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              for   ( int  w  :  G . adj ( v ))                 H . addEdge ( v ,  w );                   // check that all non-isolated vertices are conneted          int  s  =  nonIsolatedVertex ( G );          BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( H ,  s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              if   ( H . degree ( v )   >
 
0
 
&&
 
!
bfs
.
hasPathTo
(
v
))

                
return
 
false
;

        
return
 
true
;

    
}

    
// check that solution is correct

    
private
 
boolean
 certifySolution
(
Digraph
 G
)
 
{

        
// internal consistency check

        
if
 
(
hasEulerianCycle
()
 
==
 
(
cycle
()
 
==
 
null
))
 
return
 
false
;

        
// hashEulerianCycle() returns correct value

        
if
 
(
hasEulerianCycle
()
 
!=
 satisfiesNecessaryAndSufficientConditions
(
G
))
 
return
 
false
;

        
// nothing else to check if no Eulerian cycle

        
if
 
(
cycle 
==
 
null
)
 
return
 
true
;

        
// check that cycle() uses correct number of edges

        
if
 
(
cycle
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)
 
return
 
false
;

        
// check that cycle() is a directed cycle of G

        
// TODO

        
return
 
true
;

    
}

    
private
 
static
 
void
 unitTest
(
Digraph
 G
,
 
String
 description
)
 
{

        
StdOut
.
println
(
description
);

        
StdOut
.
println
(
“————————————-”
);

        
StdOut
.
print
(
G
);

        
DirectedEulerianCycle
 euler 
=
 
new
 
DirectedEulerianCycle
(
G
);

        
StdOut
.
print
(
“Eulerian cycle: ”
);

        
if
 
(
euler
.
hasEulerianCycle
())
 
{

            
for
 
(
int
 v 
:
 euler
.
cycle
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“none”
);

        
}

        
StdOut
.
println
();

    
}

    
/**

     * Unit tests the {
@code
 DirectedEulerianCycle} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// Eulerian cycle

        
Digraph
 G1 
=
 
DigraphGenerator
.
eulerianCycle
(
V
,
 E
);

        unitTest
(
G1
,
 
“Eulerian cycle”
);

        
// Eulerian path

        
Digraph
 G2 
=
 
DigraphGenerator
.
eulerianPath
(
V
,
 E
);

        unitTest
(
G2
,
 
“Eulerian path”
);

        
// empty digraph

        
Digraph
 G3 
=
 
new
 
Digraph
(
V
);

        unitTest
(
G3
,
 
“empty digraph”
);

        
// self loop

        
Digraph
 G4 
=
 
new
 
Digraph
(
V
);

        
int
 v4 
=
 
StdRandom
.
uniform
(
V
);

        G4
.
addEdge
(
v4
,
 v4
);

        unitTest
(
G4
,
 
“single self loop”
);

        
// union of two disjoint cycles

        
Digraph
 H1 
=
 
DigraphGenerator
.
eulerianCycle
(
V
/
2
,
 E
/
2
);

        
Digraph
 H2 
=
 
DigraphGenerator
.
eulerianCycle
(


 V
/
2
,
 E 

 E
/
2
);

        
int
[]
 perm 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             perm [ i ]   =  i ;          StdRandom . shuffle ( perm );          Digraph  G5  =   new   Digraph ( V );          for   ( int  v  =   0 ;  v  <  H1 . V ();  v ++ )              for   ( int  w  :  H1 . adj ( v ))                 G5 . addEdge ( perm [ v ],  perm [ w ]);          for   ( int  v  =   0 ;  v  <  H2 . V ();  v ++ )              for   ( int  w  :  H2 . adj ( v ))                 G5 . addEdge ( perm [ V / 2   +  v ],  perm [ V / 2   +  w ]);         unitTest ( G5 ,   "Union of two disjoint cycles" );          // random digraph          Digraph  G6  =   DigraphGenerator . simple ( V ,  E );         unitTest ( G6 ,   "simple digraph" );          // 4-vertex digraph          Digraph  G7  =   new   Digraph ( new   In ( "eulerianD.txt" ));         unitTest ( G7 ,   "4-vertex Eulerian digraph" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DirectedEulerianPath.java edu/princeton/cs/algs4/DirectedEulerianPath.java /******************************************************************************  *  Compilation:  javac DirectedEulerianPath.java  *  Execution:    java DirectedEulerianPath V E  *  Dependencies: Digraph.java Stack.java StdOut.java  *                BreadthFirstPaths.java  *                DigraphGenerator.java StdRandom.java  *  *  Find an Eulerian path in a digraph, if one exists.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; /**  *  The { @code  DirectedEulerianPath} class represents a data type  *  for finding an Eulerian path in a digraph.  *  An Eulerian path is a path (not necessarily simple) that

 *  uses every edge in the digraph exactly once.

 *  

 *  This implementation uses a nonrecursive depth-first search.

 *  The constructor take Θ(E + V) time

 *  in the worst case, where E is the number of edges and

 *  V is the number of vertices.

 *  It uses Θ(V) extra space (not including the digraph). 

 *  

 *  To compute Eulerian cycles in digraphs, see {
@link
 DirectedEulerianCycle}.

 *  To compute Eulerian cycles and paths in undirected graphs, see

 *  {
@link
 EulerianCycle} and {
@link
 EulerianPath}.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 * 

 * 
@author
 Robert Sedgewick

 * 
@author
 Kevin Wayne

 * 
@author
 Nate Liu

 */

public
 
class
 
DirectedEulerianPath
 
{

    
private
 
Stack
< Integer >
 path 
=
 
null
;
   
// Eulerian path; null if no suh path

    
/**

     * Computes an Eulerian path in the specified digraph, if one exists.

     * 

     * 
@param
 G the digraph

     */

    
public
 
DirectedEulerianPath
(
Digraph
 G
)
 
{

        
// find vertex from which to start potential Eulerian path:

        
// a vertex v with outdegree(v) > indegree(v) if it exits;

        
// otherwise a vertex with outdegree(v) > 0

        
int
 deficit 
=
 
0
;

        
int
 s 
=
 nonIsolatedVertex
(
G
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( G . outdegree ( v )   >
 G
.
indegree
(
v
))
 
{

                deficit 
+=
 
(
G
.
outdegree
(
v
)
 

 G
.
indegree
(
v
));

                s 
=
 v
;

            
}

        
}

        
// digraph can’t have an Eulerian path

        
// (this condition is needed)

        
if
 
(
deficit 
>
 
1
)
 
return
;

        
// special case for digraph with zero edges (has a degenerate Eulerian path)

        
if
 
(

==
 

1
)
 s 
=
 
0
;

        
// create local view of adjacency lists, to iterate one vertex at a time

        
Iterator
< Integer >
[]
 adj 
=
 
(
Iterator
< Integer >
[])
 
new
 
Iterator
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =  G . adj ( v ). iterator ();          // greedily add to cycle, depth-first search style          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        stack
.
push
(
s
);

        path 
=
 
new
 
Stack
< Integer >
();

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
pop
();

            
while
 
(
adj
[
v
].
hasNext
())
 
{

                stack
.
push
(
v
);

                v 
=
 adj
[
v
].
next
();

            
}

            
// push vertex with no more available edges to path

            path
.
push
(
v
);

        
}

            

        
// check if all edges have been used

        
if
 
(
path
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)

            path 
=
 
null
;

        
assert
 check
(
G
);

    
}

    
/**

     * Returns the sequence of vertices on an Eulerian path.

     * 

     * 
@return
 the sequence of vertices on an Eulerian path;

     *         {
@code
 null} if no such path

     */

    
public
 
Iterable
< Integer >
 path
()
 
{

        
return
 path
;

    
}

    
/**

     * Returns true if the digraph has an Eulerian path.

     * 

     * 
@return
 {
@code
 true} if the digraph has an Eulerian path;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasEulerianPath
()
 
{

        
return
 path 
!=
 
null
;

    
}

    
// returns any non-isolated vertex; -1 if no such vertex

    
private
 
static
 
int
 nonIsolatedVertex
(
Digraph
 G
)
 
{

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . outdegree ( v )   >
 
0
)

                
return
 v
;

        
return
 

1
;

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// Determines whether a digraph has an Eulerian path using necessary

    
// and sufficient conditions (without computing the path itself):

    
//    – indegree(v) = outdegree(v) for every vertex,

    
//      except one vertex v may have outdegree(v) = indegree(v) + 1

    
//      (and one vertex v may have indegree(v) = outdegree(v) + 1)

    
//    – the graph is connected, when viewed as an undirected graph

    
//      (ignoring isolated vertices)

    
private
 
static
 
boolean
 satisfiesNecessaryAndSufficientConditions
(
Digraph
 G
)
 
{

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
 
true
;

        
// Condition 1: indegree(v) == outdegree(v) for every vertex,

        
// except one vertex may have outdegree(v) = indegree(v) + 1

        
int
 deficit 
=
 
0
;

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . outdegree ( v )   >
 G
.
indegree
(
v
))

                deficit 
+=
 
(
G
.
outdegree
(
v
)
 

 G
.
indegree
(
v
));

        
if
 
(
deficit 
>
 
1
)
 
return
 
false
;

        
// Condition 2: graph is connected, ignoring isolated vertices

        
Graph
 H 
=
 
new
 
Graph
(
G
.
V
());

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              for   ( int  w  :  G . adj ( v ))                 H . addEdge ( v ,  w );                   // check that all non-isolated vertices are connected          int  s  =  nonIsolatedVertex ( G );          BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( H ,  s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              if   ( H . degree ( v )   >
 
0
 
&&
 
!
bfs
.
hasPathTo
(
v
))

                
return
 
false
;

        
return
 
true
;

    
}

    
private
 
boolean
 check
(
Digraph
 G
)
 
{

        
// internal consistency check

        
if
 
(
hasEulerianPath
()
 
==
 
(
path
()
 
==
 
null
))
 
return
 
false
;

        
// hashEulerianPath() returns correct value

        
if
 
(
hasEulerianPath
()
 
!=
 satisfiesNecessaryAndSufficientConditions
(
G
))
 
return
 
false
;

        
// nothing else to check if no Eulerian path

        
if
 
(
path 
==
 
null
)
 
return
 
true
;

        
// check that path() uses correct number of edges

        
if
 
(
path
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)
 
return
 
false
;

        
// check that path() is a directed path in G

        
// TODO

        
return
 
true
;

    
}

    
private
 
static
 
void
 unitTest
(
Digraph
 G
,
 
String
 description
)
 
{

        
StdOut
.
println
(
description
);

        
StdOut
.
println
(
“————————————-”
);

        
StdOut
.
print
(
G
);

        
DirectedEulerianPath
 euler 
=
 
new
 
DirectedEulerianPath
(
G
);

        
StdOut
.
print
(
“Eulerian path:  ”
);

        
if
 
(
euler
.
hasEulerianPath
())
 
{

            
for
 
(
int
 v 
:
 euler
.
path
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“none”
);

        
}

        
StdOut
.
println
();

    
}

    
/**

     * Unit tests the {
@code
 DirectedEulerianPath} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// Eulerian cycle

        
Digraph
 G1 
=
 
DigraphGenerator
.
eulerianCycle
(
V
,
 E
);

        unitTest
(
G1
,
 
“Eulerian cycle”
);

        
// Eulerian path

        
Digraph
 G2 
=
 
DigraphGenerator
.
eulerianPath
(
V
,
 E
);

        unitTest
(
G2
,
 
“Eulerian path”
);

        
// add one random edge

        
Digraph
 G3 
=
 
new
 
Digraph
(
G2
);

        G3
.
addEdge
(
StdRandom
.
uniform
(
V
),
 
StdRandom
.
uniform
(
V
));

        unitTest
(
G3
,
 
“one random edge added to Eulerian path”
);

        
// self loop

        
Digraph
 G4 
=
 
new
 
Digraph
(
V
);

        
int
 v4 
=
 
StdRandom
.
uniform
(
V
);

        G4
.
addEdge
(
v4
,
 v4
);

        unitTest
(
G4
,
 
“single self loop”
);

        
// single edge

        
Digraph
 G5 
=
 
new
 
Digraph
(
V
);

        G5
.
addEdge
(
StdRandom
.
uniform
(
V
),
 
StdRandom
.
uniform
(
V
));

        unitTest
(
G5
,
 
“single edge”
);

        
// empty digraph

        
Digraph
 G6 
=
 
new
 
Digraph
(
V
);

        unitTest
(
G6
,
 
“empty digraph”
);

        
// random digraph

        
Digraph
 G7 
=
 
DigraphGenerator
.
simple
(
V
,
 E
);

        unitTest
(
G7
,
 
“simple digraph”
);

        
// 4-vertex digraph

        
Digraph
 G8 
=
 
new
 
Digraph
(
new
 
In
(
“eulerianD.txt”
));

        unitTest
(
G8
,
 
“4-vertex Eulerian digraph”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/DoublingRatio.java
edu/princeton/cs/algs4/DoublingRatio.java
/******************************************************************************

 *  Compilation:  javac DoublingRatio.java

 *  Execution:    java DoublingRatio

 *  Dependencies: ThreeSum.java Stopwatch.java StdRandom.java StdOut.java

 *

 *

 *  % java DoublingRatio

 *      250     0.0   2.7

 *      500     0.0   4.8

 *     1000     0.1   6.9

 *     2000     0.6   7.7

 *     4000     4.5   8.0

 *     8000    35.7   8.0

 *     4000     3.9   6.6

 *  …

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 DoublingRatio} class provides a client for measuring

 *  the running time of a method using a doubling ratio test.

 *  

 *  For additional documentation, see Section 1.4

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DoublingRatio
 
{

    
private
 
static
 
final
 
int
 MAXIMUM_INTEGER 
=
 
1000000
;

    
// This class should not be instantiated.

    
private
 
DoublingRatio
()
 
{
 
}

    
/**

     * Returns the amount of time to call {
@code
 ThreeSum.count()} with n

     * random 6-digit integers.

     * 
@param
 n the number of integers

     * 
@return
 amount of time (in seconds) to call {
@code
 ThreeSum.count()}

     *   with n random 6-digit integers

     */

    
public
 
static
 
double
 timeTrial
(
int
 n
)
 
{

        
int
[]
 a 
=
 
new
 
int
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             a [ i ]   =   StdRandom . uniform ( - MAXIMUM_INTEGER ,  MAXIMUM_INTEGER );          }          Stopwatch  timer  =   new   Stopwatch ();          ThreeSum . count ( a );          return  timer . elapsedTime ();      }      /**      * Prints table of running times to call { @code  ThreeSum.count()}      * for arrays of size 250, 500, 1000, 2000, and so forth, along      * with ratios of running times between successive array sizes.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            double  prev  =  timeTrial ( 125 );          for   ( int  n  =   250 ;   true ;  n  +=  n )   {              double  time  =  timeTrial ( n );              StdOut . printf ( "%7d %7.1f %5.1f\n" ,  n ,  time ,  time / prev );             prev  =  time ;          }        }   }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/DoublingTest.java edu/princeton/cs/algs4/DoublingTest.java /******************************************************************************  *  Compilation:  javac DoublingTest.java  *  Execution:    java DoublingTest  *  Dependencies: ThreeSum.java Stopwatch.java StdRandom.java StdOut.java  *  *  % java DoublingTest   *      250     0.0  *      500     0.0  *     1000     0.1  *     2000     0.6  *     4000     4.5  *     8000    35.7  *  ...  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  DoublingTest} class provides a client for measuring  *  the running time of a method using a doubling test.  *  

 *  For additional documentation, see Section 1.4

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
DoublingTest
 
{

    
private
 
static
 
final
 
int
 MAXIMUM_INTEGER 
=
 
1000000
;

    
// This class should not be instantiated.

    
private
 
DoublingTest
()
 
{
 
}

    
/**

     * Returns the amount of time to call {
@code
 ThreeSum.count()} with n

     * random 6-digit integers.

     * 
@param
 n the number of integers

     * 
@return
 amount of time (in seconds) to call {
@code
 ThreeSum.count()}

     *   with n random 6-digit integers

     */

    
public
 
static
 
double
 timeTrial
(
int
 n
)
 
{

        
int
[]
 a 
=
 
new
 
int
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             a [ i ]   =   StdRandom . uniform ( - MAXIMUM_INTEGER ,  MAXIMUM_INTEGER );          }          Stopwatch  timer  =   new   Stopwatch ();          ThreeSum . count ( a );          return  timer . elapsedTime ();      }      /**      * Prints table of running times to call { @code  ThreeSum.count()}      * for arrays of size 250, 500, 1000, 2000, and so forth.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            for   ( int  n  =   250 ;   true ;  n  +=  n )   {              double  time  =  timeTrial ( n );              StdOut . printf ( "%7d %7.1f\n" ,  n ,  time );          }        }   } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Draw.java edu/princeton/cs/algs4/Draw.java /******************************************************************************  *  Compilation:  javac Draw.java  *  Execution:    java Draw  *  Dependencies: none  *  *  Drawing library. This class provides a basic capability for creating  *  drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of points, lines, and curves  *  in a window on your computer and to save the drawings to a file.  *  This is the object-oriented version of standard draw; it supports  *  multiple indepedent drawing windows.  *  *  Todo  *  ----  *    -  Add support for gradient fill, etc.  *  *  Remarks  *  -------  *    -  don't use AffineTransform for rescaling since it inverts  *       images and strings  *    -  careful using setFont in inner loop within an animation -  *       it can cause flicker  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . BasicStroke ; import  java . awt . Color ; import  java . awt . Component ; import  java . awt . FileDialog ; import  java . awt . Font ; import  java . awt . FontMetrics ; import  java . awt . Graphics ; import  java . awt . Graphics2D ; import  java . awt . Image ; import  java . awt . MediaTracker ; import  java . awt . RenderingHints ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . MouseEvent ; import  java . awt . event . MouseListener ; import  java . awt . event . MouseMotionListener ; import  java . awt . event . KeyEvent ; import  java . awt . event . KeyListener ; import  java . awt . geom . Arc2D ; import  java . awt . geom . Ellipse2D ; import  java . awt . geom . GeneralPath ; import  java . awt . geom . Line2D ; import  java . awt . geom . Rectangle2D ; import  java . awt . image . BufferedImage ; import  java . awt . image . DirectColorModel ; import  java . awt . image . WritableRaster ; import  java . io . File ; import  java . io . IOException ; import  java . net . MalformedURLException ; import  java . net . URL ; import  java . util . ArrayList ; import  java . util . LinkedList ; import  java . util . TreeSet ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . KeyStroke ; /**  *  Draw. This class provides a basic capability for

 *  creating drawings with your programs. It uses a simple graphics model that

 *  allows you to create drawings consisting of points, lines, and curves

 *  in a window on your computer and to save the drawings to a file.

 *  This is the object-oriented version of standard draw; it supports

 *  multiple indepedent drawing windows.

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
Draw
 
implements
 
ActionListener
,
 
MouseListener
,
 
MouseMotionListener
,
 
KeyListener
 
{

    
/**

     *  The color black.

     */

    
public
 
static
 
final
 
Color
 BLACK 
=
 
Color
.
BLACK
;

    
/**

     *  The color blue.

     */

    
public
 
static
 
final
 
Color
 BLUE 
=
 
Color
.
BLUE
;

    
/**

     *  The color cyan.

     */

    
public
 
static
 
final
 
Color
 CYAN 
=
 
Color
.
CYAN
;

    
/**

     *  The color dark gray.

     */

    
public
 
static
 
final
 
Color
 DARK_GRAY 
=
 
Color
.
DARK_GRAY
;

    
/**

     *  The color gray.

     */

    
public
 
static
 
final
 
Color
 GRAY 
=
 
Color
.
GRAY
;

    
/**

     *  The color green.

     */

    
public
 
static
 
final
 
Color
 GREEN  
=
 
Color
.
GREEN
;

    
/**

     *  The color light gray.

     */

    
public
 
static
 
final
 
Color
 LIGHT_GRAY 
=
 
Color
.
LIGHT_GRAY
;

    
/**

     *  The color magenta.

     */

    
public
 
static
 
final
 
Color
 MAGENTA 
=
 
Color
.
MAGENTA
;

    
/**

     *  The color orange.

     */

    
public
 
static
 
final
 
Color
 ORANGE 
=
 
Color
.
ORANGE
;

    
/**

     *  The color pink.

     */

    
public
 
static
 
final
 
Color
 PINK 
=
 
Color
.
PINK
;

    
/**

     *  The color red.

     */

    
public
 
static
 
final
 
Color
 RED 
=
 
Color
.
RED
;

    
/**

     *  The color white.

     */

    
public
 
static
 
final
 
Color
 WHITE 
=
 
Color
.
WHITE
;

    
/**

     *  The color yellow.

     */

    
public
 
static
 
final
 
Color
 YELLOW 
=
 
Color
.
YELLOW
;

    
/**

     * Shade of blue used in Introduction to Programming in Java.

     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).

     */

    
public
 
static
 
final
 
Color
 BOOK_BLUE 
=
 
new
 
Color
(
9
,
 
90
,
 
166
);

    
/**

     * Shade of light blue used in Introduction to Programming in Java.

     * The RGB values are approximately (103, 198, 243).

     */

    
public
 
static
 
final
 
Color
 BOOK_LIGHT_BLUE 
=
 
new
 
Color
(
103
,
 
198
,
 
243
);

    

    
/**

     * Shade of red used in Algorithms, 4th edition.

     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).

     */

    
public
 
static
 
final
 
Color
 BOOK_RED 
=
 
new
 
Color
(
150
,
 
35
,
 
31
);

    
/**

     * Shade of orange used in Princeton’s identity.

     * It is PMS 158. The RGB values are approximately (245, 128, 37).

     */

    
public
 
static
 
final
 
Color
 PRINCETON_ORANGE 
=
 
new
 
Color
(
245
,
 
128
,
 
37
);

    
// default colors

    
private
 
static
 
final
 
Color
 DEFAULT_PEN_COLOR   
=
 BLACK
;

    
private
 
static
 
final
 
Color
 DEFAULT_CLEAR_COLOR 
=
 WHITE
;

    
// boundary of drawing canvas, 0% border

    
private
 
static
 
final
 
double
 BORDER 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMAX 
=
 
1.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMAX 
=
 
1.0
;

    
// default canvas size is SIZE-by-SIZE

    
private
 
static
 
final
 
int
 DEFAULT_SIZE 
=
 
512
;

    
// default pen radius

    
private
 
static
 
final
 
double
 DEFAULT_PEN_RADIUS 
=
 
0.002
;

    
// default font

    
private
 
static
 
final
 
Font
 DEFAULT_FONT 
=
 
new
 
Font
(
“SansSerif”
,
 
Font
.
PLAIN
,
 
16
);

    
// current pen color

    
private
 
Color
 penColor
;

    
// canvas size

    
private
 
int
 width  
=
 DEFAULT_SIZE
;

    
private
 
int
 height 
=
 DEFAULT_SIZE
;

    
// current pen radius

    
private
 
double
 penRadius
;

    
// show we draw immediately or wait until next show?

    
private
 
boolean
 defer 
=
 
false
;

    
private
 
double
 xmin
,
 ymin
,
 xmax
,
 ymax
;

    
// name of window

    
private
 
String
 name 
=
 
“Draw”
;

    
// for synchronization

    
private
 
final
 
Object
 mouseLock 
=
 
new
 
Object
();

    
private
 
final
 
Object
 keyLock 
=
 
new
 
Object
();

    
// current font

    
private
 
Font
 font
;

    
// the JLabel for drawing

    
private
 
JLabel
 draw
;

    
// double buffered graphics

    
private
 
BufferedImage
 offscreenImage
,
 onscreenImage
;

    
private
 
Graphics2D
 offscreen
,
 onscreen
;

    
// the frame for drawing to the screen

    
private
 
JFrame
 frame 
=
 
new
 
JFrame
();

    
// mouse state

    
private
 
boolean
 isMousePressed 
=
 
false
;

    
private
 
double
 mouseX 
=
 
0
;

    
private
 
double
 mouseY 
=
 
0
;

    
// keyboard state

    
private
 
final
 
LinkedList
< Character >
 keysTyped 
=
 
new
 
LinkedList
< Character >
();

    
private
 
final
 
TreeSet
< Integer >
 keysDown 
=
 
new
 
TreeSet
< Integer >
();

    
// event-based listeners

    
private
 
final
 
ArrayList
< DrawListener >
 listeners 
=
 
new
 
ArrayList
< DrawListener >
();

    
/**

     * Initializes an empty drawing object with the given name.

     *

     * 
@param
 name the title of the drawing window.

     */

    
public
 
Draw
(
String
 name
)
 
{

        
this
.
name 
=
 name
;

        init
();

    
}

    
/**

     * Initializes an empty drawing object.

     */

    
public
 
Draw
()
 
{

        init
();

    
}

    
private
 
void
 init
()
 
{

        
if
 
(
frame 
!=
 
null
)
 frame
.
setVisible
(
false
);

        frame 
=
 
new
 
JFrame
();

        offscreenImage 
=
 
new
 
BufferedImage
(
2
*
width
,
 
2
*
height
,
 
BufferedImage
.
TYPE_INT_ARGB
);

        onscreenImage  
=
 
new
 
BufferedImage
(
2
*
width
,
 
2
*
height
,
 
BufferedImage
.
TYPE_INT_ARGB
);

        offscreen 
=
 offscreenImage
.
createGraphics
();

        onscreen  
=
 onscreenImage
.
createGraphics
();

        offscreen
.
scale
(
2.0
,
 
2.0
);
  
// since we made it 2x as big

        setXscale
();

        setYscale
();

        offscreen
.
setColor
(
DEFAULT_CLEAR_COLOR
);

        offscreen
.
fillRect
(
0
,
 
0
,
 width
,
 height
);

        setPenColor
();

        setPenRadius
();

        setFont
();

        clear
();

        
// add antialiasing

        
RenderingHints
 hints 
=
 
new
 
RenderingHints
(
RenderingHints
.
KEY_ANTIALIASING
,

                                                  
RenderingHints
.
VALUE_ANTIALIAS_ON
);

        hints
.
put
(
RenderingHints
.
KEY_RENDERING
,
 
RenderingHints
.
VALUE_RENDER_QUALITY
);

        offscreen
.
addRenderingHints
(
hints
);

        
// frame stuff

        
RetinaImageIcon
 icon 
=
 
new
 
RetinaImageIcon
(
onscreenImage
);

        draw 
=
 
new
 
JLabel
(
icon
);

        draw
.
addMouseListener
(
this
);

        draw
.
addMouseMotionListener
(
this
);

        frame
.
setContentPane
(
draw
);

        frame
.
addKeyListener
(
this
);
    
// JLabel cannot get keyboard focus

        frame
.
setResizable
(
false
);

        
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            // closes all windows

        frame
.
setDefaultCloseOperation
(
JFrame
.
DISPOSE_ON_CLOSE
);
      
// closes only current window

        frame
.
setFocusTraversalKeysEnabled
(
false
);
  
// to recognize VK_TAB with isKeyPressed()

        frame
.
setTitle
(
name
);

        frame
.
setJMenuBar
(
createMenuBar
());

        frame
.
pack
();

        frame
.
requestFocusInWindow
();

        frame
.
setVisible
(
true
);

    
}

    
/**

     * Sets the upper-left hand corner of the drawing window to be (x, y), where (0, 0) is upper left.

     *

     * 
@param
  x the number of pixels from the left

     * 
@param
  y the number of pixels from the top

     * 
@throws
 IllegalArgumentException if the width or height is 0 or negative

     */

    
public
 
void
 setLocationOnScreen
(
int
 x
,
 
int
 y
)
 
{

        
if
 
(

<=   0   ||  y  <=   0 )   throw   new   IllegalArgumentException ();         frame . setLocation ( x ,  y );      }      /**      * Sets the default close operation.      *      *  @param   value the value, typically { @code  JFrame.EXIT_ON_CLOSE}      *         (close all windows) or { @code  JFrame.DISPOSE_ON_CLOSE}      *         (close current window)      */      public   void  setDefaultCloseOperation ( int  value )   {         frame . setDefaultCloseOperation ( value );      }              /**      * Sets the canvas (drawing area) to be width-by-height pixels.

     * This also erases the current drawing and resets the coordinate system, pen radius,

     * pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning of a program.

     *

     * 
@param
  canvasWidth the width as a number of pixels

     * 
@param
  canvasHeight the height as a number of pixels

     * 
@throws
 IllegalArgumentException unless both {
@code
 canvasWidth}

     *         and {
@code
 canvasHeight} are positive

     */

    
public
 
void
 setCanvasSize
(
int
 canvasWidth
,
 
int
 canvasHeight
)
 
{

        
if
 
(
canvasWidth 
<   1   ||  canvasHeight  <   1 )   {              throw   new   IllegalArgumentException ( "width and height must be positive" );          }         width  =  canvasWidth ;         height  =  canvasHeight ;         init ();      }      // create the menu bar (changed to private)      private   JMenuBar  createMenuBar ()   {          JMenuBar  menuBar  =   new   JMenuBar ();          JMenu  menu  =   new   JMenu ( "File" );         menuBar . add ( menu );          JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );         menuItem1 . addActionListener ( this );          // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()         menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                  Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));         menu . add ( menuItem1 );          return  menuBar ;      }     /***************************************************************************     *  User and screen coordinate systems.     ***************************************************************************/      // throw an IllegalArgumentException if x is NaN or infinite      private   static   void  validate ( double  x ,   String  name )   {          if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );          if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNonnegative ( double  x ,   String  name )   {          if   ( x  <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNotNull ( Object  x ,   String  name )   {          if   ( x  ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );      }      /**      * Sets the x-scale to be the default (between 0.0 and 1.0).      */      public   void  setXscale ()   {         setXscale ( DEFAULT_XMIN ,  DEFAULT_XMAX );      }      /**      * Sets the y-scale to be the default (between 0.0 and 1.0).      */      public   void  setYscale ()   {         setYscale ( DEFAULT_YMIN ,  DEFAULT_YMAX );      }      /**      * Sets the x-scale.      *      *  @param  min the minimum value of the x-scale      *  @param  max the maximum value of the x-scale      *  @throws  IllegalArgumentException if { @code  (max == min)}      *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite      */      public   void  setXscale ( double  min ,   double  max )   {         validate ( min ,   "min" );         validate ( max ,   "max" );          double  size  =  max  -  min ;          if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );         xmin  =  min  -  BORDER  *  size ;         xmax  =  max  +  BORDER  *  size ;      }      /**      * Sets the y-scale.      *      *  @param  min the minimum value of the y-scale      *  @param  max the maximum value of the y-scale      *  @throws  IllegalArgumentException if { @code  (max == min)}      *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite      */      public   void  setYscale ( double  min ,   double  max )   {         validate ( min ,   "min" );         validate ( max ,   "max" );          double  size  =  max  -  min ;          if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );         ymin  =  min  -  BORDER  *  size ;         ymax  =  max  +  BORDER  *  size ;      }      // helper functions that scale from user coordinates to screen coordinates and back      private   double   scaleX ( double  x )   {   return  width   *   ( x  -  xmin )   /   ( xmax  -  xmin );   }      private   double   scaleY ( double  y )   {   return  height  *   ( ymax  -  y )   /   ( ymax  -  ymin );   }      private   double  factorX ( double  w )   {   return  w  *  width   /   Math . abs ( xmax  -  xmin );    }      private   double  factorY ( double  h )   {   return  h  *  height  /   Math . abs ( ymax  -  ymin );    }      private   double    userX ( double  x )   {   return  xmin  +  x  *   ( xmax  -  xmin )   /  width ;      }      private   double    userY ( double  y )   {   return  ymax  -  y  *   ( ymax  -  ymin )   /  height ;     }      /**      * Clears the screen to the default color (white).      */      public   void  clear ()   {         clear ( DEFAULT_CLEAR_COLOR );      }      /**      * Clears the screen to the given color.      *      *  @param  color the color to make the background      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  clear ( Color  color )   {         validateNotNull ( color ,   "color" );         offscreen . setColor ( color );         offscreen . fillRect ( 0 ,   0 ,  width ,  height );         offscreen . setColor ( penColor );         draw ();      }      /**      * Gets the current pen radius.      *      *  @return  the current pen radius      */      public   double  getPenRadius ()   {          return  penRadius ;      }      /**      * Sets the pen size to the default (.002).      */      public   void  setPenRadius ()   {         setPenRadius ( DEFAULT_PEN_RADIUS );      }      /**      * Sets the radius of the pen to the given size.      *      *  @param   radius the radius of the pen      *  @throws  IllegalArgumentException if { @code  radius} is negative, NaN, or infinite      */      public   void  setPenRadius ( double  radius )   {         validate ( radius ,   "pen radius" );         validateNonnegative ( radius ,   "pen radius" );         penRadius  =  radius  *  DEFAULT_SIZE ;          BasicStroke  stroke  =   new   BasicStroke (( float )  penRadius ,   BasicStroke . CAP_ROUND ,   BasicStroke . JOIN_ROUND );          // BasicStroke stroke = new BasicStroke((float) penRadius);         offscreen . setStroke ( stroke );      }      /**      * Gets the current pen color.      *      *  @return  the current pen color      */      public   Color  getPenColor ()   {          return  penColor ;      }      /**      * Sets the pen color to the default color (black).      */      public   void  setPenColor ()   {         setPenColor ( DEFAULT_PEN_COLOR );      }      /**      * Sets the pen color to the given color.      *      *  @param  color the color to make the pen      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  setPenColor ( Color  color )   {         validateNotNull ( color ,   "color" );         penColor  =  color ;         offscreen . setColor ( penColor );      }      /**      * Sets the pen color to the given RGB color.      *      *  @param   red the amount of red (between 0 and 255)      *  @param   green the amount of green (between 0 and 255)      *  @param   blue the amount of blue (between 0 and 255)      *  @throws  IllegalArgumentException if { @code  red}, { @code  green},      *         or { @code  blue} is outside its prescribed range      */      public   void  setPenColor ( int  red ,   int  green ,   int  blue )   {          if   ( red    <   0   ||  red    >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“red must be between 0 and 255”
);

        
if
 
(
green 
<   0   ||  green  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“green must be between 0 and 255”
);

        
if
 
(
blue  
<   0   ||  blue   >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“blue must be between 0 and 255”
);

        setPenColor
(
new
 
Color
(
red
,
 green
,
 blue
));

    
}

    
/**

     * Turns on xor mode.

     */

    
public
 
void
 xorOn
()
 
{

        offscreen
.
setXORMode
(
DEFAULT_CLEAR_COLOR
);

    
}

    
/**

     * Turns off xor mode.

     */

    
public
 
void
 xorOff
()
 
{

        offscreen
.
setPaintMode
();

    
}

    
/**

     * Gets the current {
@code
 JLabel} for use in some other GUI.

     *

     * 
@return
 the current {
@code
 JLabel}

     */

    
public
 
JLabel
 getJLabel
()
 
{

        
return
 draw
;

    
}

    
/**

     * Gets the current font.

     *

     * 
@return
 the current font

     */

    
public
 
Font
 getFont
()
 
{

        
return
 font
;

    
}

    
/**

     * Sets the font to the default font (sans serif, 16 point).

     */

    
public
 
void
 setFont
()
 
{

        setFont
(
DEFAULT_FONT
);

    
}

    
/**

     * Sets the font to the given value.

     *

     * 
@param
 font the font

     * 
@throws
 IllegalArgumentException if {
@code
 font} is {
@code
 null}

     */

    
public
 
void
 setFont
(
Font
 font
)
 
{

        validateNotNull
(
font
,
 
“font”
);

        
this
.
font 
=
 font
;

    
}

   
/***************************************************************************

    *  Drawing geometric shapes.

    ***************************************************************************/

    
/**

     * Draws a line from (x0, y0) to (x1, y1).

     *

     * 
@param
 x0 the x-coordinate of the starting point

     * 
@param
 y0 the y-coordinate of the starting point

     * 
@param
 x1 the x-coordinate of the destination point

     * 
@param
 y1 the y-coordinate of the destination point

     * 
@throws
 IllegalArgumentException if any coordinate is either NaN or infinite

     */

    
public
 
void
 line
(
double
 x0
,
 
double
 y0
,
 
double
 x1
,
 
double
 y1
)
 
{

        validate
(
x0
,
 
“x0”
);

        validate
(
y0
,
 
“y0”
);

        validate
(
x1
,
 
“x1”
);

        validate
(
y1
,
 
“y1”
);

        offscreen
.
draw
(
new
 
Line2D
.
Double
(
scaleX
(
x0
),
 scaleY
(
y0
),
 scaleX
(
x1
),
 scaleY
(
y1
)));

        draw
();

    
}

    
/**

     * Draws one pixel at (x, y).

     *

     * 
@param
 x the x-coordinate of the pixel

     * 
@param
 y the y-coordinate of the pixel

     * 
@throws
 IllegalArgumentException if {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
private
 
void
 pixel
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        offscreen
.
fillRect
((
int
)
 
Math
.
round
(
scaleX
(
x
)),
 
(
int
)
 
Math
.
round
(
scaleY
(
y
)),
 
1
,
 
1
);

    
}

    
/**

     * Draws a point at (x, y).

     *

     * 
@param
 x the x-coordinate of the point

     * 
@param
 y the y-coordinate of the point

     * 
@throws
 IllegalArgumentException if either {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
public
 
void
 point
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 r 
=
 penRadius
;

        
// double ws = factorX(2*r);

        
// double hs = factorY(2*r);

        
// if (ws <= 1 && hs <= 1) pixel(x, y);          if   ( r  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  r / 2 ,  ys  -  r / 2 ,  r ,  r ));         draw ();      }      /**      * Draws a circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 circle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“radius”
);

        validateNonnegative
(
radius
,
 
“radius”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
radius
);

        
double
 hs 
=
 factorY
(
2
*
radius
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a filled circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 filledCircle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate(radius, “radius”);

        validateNonnegative(radius, “radius”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*radius);

        double hs = factorY(2*radius);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws an ellipse with the specified semimajor and semiminor axes,     * centered at (xy).     *     * @param  x the x-coordinate of the center of the ellipse     * @param  y the y-coordinate of the center of the ellipse     * @param  semiMajorAxis is the semimajor axis of the ellipse     * @param  semiMinorAxis is the semiminor axis of the ellipse     * @throws IllegalArgumentException if either {@code semiMajorAxis}     *         or {@code semiMinorAxis} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void ellipse(double x, double y, double semiMajorAxis, double semiMinorAxis) {

        validate(x, “x”);

        validate(y, “y”);

        validate(semiMajorAxis, “semimajor axis”);

        validate(semiMinorAxis, “semiminor axis”);

        validateNonnegative(semiMajorAxis, “semimajor axis”);

        validateNonnegative(semiMinorAxis, “semiminor axis”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*semiMajorAxis);

        double hs = factorY(2*semiMinorAxis);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled ellipse with the specified semimajor and semiminor axes,     * centered at (xy).     *     * @param  x the x-coordinate of the center of the ellipse     * @param  y the y-coordinate of the center of the ellipse     * @param  semiMajorAxis is the semimajor axis of the ellipse     * @param  semiMinorAxis is the semiminor axis of the ellipse     * @throws IllegalArgumentException if either {@code semiMajorAxis}     *         or {@code semiMinorAxis} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void filledEllipse(double x, double y, double semiMajorAxis, double semiMinorAxis) {

        validate(x, “x”);

        validate(y, “y”);

        validate(semiMajorAxis, “semimajor axis”);

        validate(semiMinorAxis, “semiminor axis”);

        validateNonnegative(semiMajorAxis, “semimajor axis”);

        validateNonnegative(semiMinorAxis, “semiminor axis”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*semiMajorAxis);

        double hs = factorY(2*semiMinorAxis);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a circular arc of the specified radius,     * centered at (xy), from angle1 to angle2 (in degrees).     *     * @param  x the x-coordinate of the center of the circle     * @param  y the y-coordinate of the center of the circle     * @param  radius the radius of the circle     * @param  angle1 the starting angle. 0 would mean an arc beginning at 3 o’clock.     * @param  angle2 the angle at the end of the arc. For example, if     *         you want a 90 degree arc, then angle2 should be angle1 + 90.     * @throws IllegalArgumentException if {@code radius} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void arc(double x, double y, double radius, double angle1, double angle2) {

        validate(x, “x”);

        validate(y, “y”);

        validate(radius, “arc radius”);

        validate(angle1, “angle1”);

        validate(angle2, “angle2”);

        validateNonnegative(radius, “arc radius”);

        while (angle2 < angle1) angle2 += 360;         double xs = scaleX(x);         double ys = scaleY(y);         double ws = factorX(2*radius);         double hs = factorY(2*radius);         if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Arc2D.Double(xs - ws/2, ys - hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void square(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void filledSquare(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void rectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void filledRectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public void polygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.draw(path);         draw();     }     /**     * Draws a filled polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public void filledPolygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.fill(path);         draw();     }    /***************************************************************************    *  Drawing images.    ***************************************************************************/     // get an image from the given filename    private static Image getImage(String filename) {         if (filename == null) throw new IllegalArgumentException();         // to read from file        ImageIcon icon = new ImageIcon(filename);         // try to read from URL        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             try {                 URL url = new URL(filename);                 icon = new ImageIcon(url);             }             catch (MalformedURLException e) {                 /* not a url */             }         }         // in case file is inside a .jar (classpath relative to StdDraw)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource(filename);             if (url != null)                 icon = new ImageIcon(url);         }         // in case file is inside a .jar (classpath relative to root of jar)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = Draw.class.getResource("/" + filename);             if (url == null) throw new IllegalArgumentException("image " + filename + " not found");             icon = new ImageIcon(url);         }         return icon.getImage();     }     /**     * Draws the specified image centered at (xy).     * The supported image formats are JPEG, PNG, and GIF.     * As an optimization, the picture is cached, so there is no performance     * penalty for redrawing the same image multiple times (e.g., in an animation).     * However, if you change the picture file after drawing it, subsequent     * calls will draw the original picture.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if either {@code x} or {@code y} is either NaN or infinite     */

    public void picture(double x, double y, String filename) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(filename, “filename”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         draw();     }     /**     * Draws the specified image centered at (xy),     * rotated given number of degrees.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x}, {@code y}, {@code degrees} is NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void picture(double x, double y, String filename, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }     /**     * Draws the specified image centered at (xy),     * rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void picture(double x, double y, String filename, double scaledWidth, double scaledHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         else {             offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                        (int) Math.round(ys - hs/2.0),                                        (int) Math.round(ws),                                        (int) Math.round(hs), null);         }         draw();     }     /**     * Draws the specified image centered at (xy), rotated     * given number of degrees, and rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     */

    public void picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                    (int) Math.round(ys - hs/2.0),                                    (int) Math.round(ws),                                    (int) Math.round(hs), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }    /***************************************************************************    *  Drawing text.    ***************************************************************************/     /**     * Writes the given text string in the current font, centered at (xy).     *     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void text(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws/2.0), (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, centered at (xy) and     * rotated by the specified number of degrees.     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x}, {@code y}, or {@code degrees} is either NaN or infinite     */

    public void text(double x, double y, String text, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(text, “text”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        offscreen.rotate(Math.toRadians(-degrees), xs, ys);

        text(x, y, text);

        offscreen.rotate(Math.toRadians(+degrees), xs, ys);

    }

    /**     * Writes the given text string in the current font, left-aligned at (xy).     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void textLeft(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = metrics.stringWidth(text);        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) xs, (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, right-aligned at (xy).     *     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void textRight(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws), (float) (ys + hs));

        draw();

    }

    /**     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds     * and enables double buffering.     * @param t number of milliseconds     * @deprecated replaced by {@link #enableDoubleBuffering()}, {@link #show()}, and {@link #pause(int t)}     */

    @Deprecated

    public void show(int t) {

        show();

        pause(t);

        enableDoubleBuffering();

    }

    /**     * Pause for t milliseconds. This method is intended to support computer animations.     * @param t number of milliseconds     */

    public void pause(int t) {

        try {

            Thread.sleep(t);

        }

        catch (InterruptedException e) {

            System.out.println(“Error sleeping”);

        }

    }

    /**     * Copies offscreen buffer to onscreen buffer. There is no reason to call     * this method unless double buffering is enabled.     */

    public void show() {

        onscreen.drawImage(offscreenImage, 0, 0, null);

        frame.repaint();

    }

    // draw onscreen if defer is false    private void draw() {

        if (!defer) show();

    }

    /**     * Enable double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be deferred until the next call     * to show(). Useful for animations.     */

    public void enableDoubleBuffering() {

        defer = true;

    }

    /**     * Disable double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be displayed on screen when called.     * This is the default.     */

    public void disableDoubleBuffering() {

        defer = false;

    }

    /**     * Saves the drawing to using the specified filename.     * The supported image formats are JPEG and PNG;     * the filename suffix must be {@code  } or {@code  }.     *     * @param  filename the name of the file with one of the required suffixes     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void save(String filename) {

        validateNotNull(filename, “filename”);

        File file = new File(filename);

        String suffix = filename.substring(filename.lastIndexOf(‘.’) + 1);

        // png files        if (“png”.equalsIgnoreCase(suffix)) {

            try {

                ImageIO.write(offscreenImage, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        // need to change from ARGB to RGB for jpeg        // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727        else if (“jpg”.equalsIgnoreCase(suffix)) {

            WritableRaster raster = offscreenImage.getRaster();

            WritableRaster newRaster;

            newRaster = raster.createWritableChild(0, 0, width, height, 0, 0, new int[] {0, 1, 2});

            DirectColorModel cm = (DirectColorModel) offscreenImage.getColorModel();

            DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(),

                                                          cm.getRedMask(),

                                                          cm.getGreenMask(),

                                                          cm.getBlueMask());

            BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false,  null);

            try {

                ImageIO.write(rgbBuffer, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        else {

            System.out.println(“Invalid image file type: ” + suffix);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void actionPerformed(ActionEvent e) {

        FileDialog chooser = new FileDialog(frame, “Use a   or   extension”, FileDialog.SAVE);

        chooser.setVisible(true);

        String filename = chooser.getFile();

        if (filename != null) {

            save(chooser.getDirectory() + File.separator + chooser.getFile());

        }

    }

   /***************************************************************************    *  Event-based interactions.    ***************************************************************************/

    /**     * Adds a {@link DrawListener} to listen to keyboard and mouse events.     *     * @param listener the {\tt DrawListener} argument     */

    public void addListener(DrawListener listener) {

        // ensure there is a window for listenting to events        show();

        listeners.add(listener);

        frame.addKeyListener(this);

        frame.addMouseListener(this);

        frame.addMouseMotionListener(this);

        frame.setFocusable(true);     }

   /***************************************************************************    *  Mouse interactions.    ***************************************************************************/

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed;     *         {@code false} otherwise     */

    public boolean isMousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed;     *         {@code false} otherwise     * @deprecated replaced by {@link #isMousePressed()}     */

    @Deprecated

    public boolean mousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns the x-coordinate of the mouse.     * @return the x-coordinate of the mouse     */

    public double mouseX() {

        synchronized (mouseLock) {

            return mouseX;

        }

    }

    /**     * Returns the y-coordinate of the mouse.     *     * @return the y-coordinate of the mouse     */

    public double mouseY() {

        synchronized (mouseLock) {

            return mouseY;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseEntered(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseExited(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mousePressed(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

            isMousePressed = true;

        }

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mousePressed(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseReleased(MouseEvent e) {

        synchronized (mouseLock) {

            isMousePressed = false;

        }

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mouseReleased(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseClicked(MouseEvent e) {

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mouseClicked(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseDragged(MouseEvent e)  {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

        }

        // doesn’t seem to work if a button is specified        for (DrawListener listener : listeners)

            listener.mouseDragged(userX(e.getX()), userY(e.getY()));

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseMoved(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

        }

    }

   /***************************************************************************    *  Keyboard interactions.    ***************************************************************************/

    /**     * Returns true if the user has typed a key.     *     * @return {@code true} if the user has typed a key; {@code false} otherwise     */

    public boolean hasNextKeyTyped() {

        synchronized (keyLock) {

            return !keysTyped.isEmpty();

        }

    }

    /**     * The next key typed by the user.     *     * @return the next key typed by the user     */

    public char nextKeyTyped() {

        synchronized (keyLock) {

            return keysTyped.removeLast();

        }

    }

   /**     * Returns true if the keycode is being pressed.     * 

     * This method takes as an argument the keycode (corresponding to a physical key).     * It can handle action keys (such as F1 and arrow keys) and modifier keys     * (such as shift and control).     * See {@link KeyEvent} for a description of key codes.     *     * @param  keycode the keycode to check     * @return {@code true} if {@code keycode} is currently being pressed;     *         {@code false} otherwise     */

    public boolean isKeyPressed(int keycode) {

        synchronized (keyLock) {

            return keysDown.contains(keycode);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyTyped(KeyEvent e) {

        synchronized (keyLock) {

            keysTyped.addFirst(e.getKeyChar());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyTyped(e.getKeyChar());

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyPressed(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.add(e.getKeyCode());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyPressed(e.getKeyCode());

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyReleased(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.remove(e.getKeyCode());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyReleased(e.getKeyCode());

    }

   /***************************************************************************    *  For improved resolution on Mac Retina displays.    ***************************************************************************/

    private static class RetinaImageIcon extends ImageIcon {

            public RetinaImageIcon(Image image) {

            super(image);

        }

        public int getIconWidth() {

            return super.getIconWidth() / 2;

        }

        /**         * Gets the height of the icon.         *         * @return the height in pixels of this icon         */

        public int getIconHeight() {

            return super.getIconHeight() / 2;

        }

        public synchronized void paintIcon(Component c, Graphics g, int x, int y) {

            Graphics2D g2 = (Graphics2D) g.create();

            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);

            g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

            g2.scale(0.5, 0.5);

            super.paintIcon(c, g2, x * 2, y * 2);

            g2.dispose();

        }

    }

    /**     * Test client.     *     * @param args the command-line arguments     */

    public static void main(String[] args) {

        // create one drawing window        Draw draw1 = new Draw(“Test client 1”);

        draw1.square(0.2, 0.8, 0.1);

        draw1.filledSquare(0.8, 0.8, 0.2);

        draw1.circle(0.8, 0.2, 0.2);

        draw1.setPenColor(Draw.MAGENTA);

        draw1.setPenRadius(0.02);

        draw1.arc(0.8, 0.2, 0.1, 200, 45);

        // create another one        Draw draw2 = new Draw(“Test client 2”);

        draw2.setCanvasSize(900, 200);

        // draw a blue diamond        draw2.setPenRadius();

        draw2.setPenColor(Draw.BLUE);

        double[] x = { 0.1, 0.2, 0.3, 0.2 };

        double[] y = { 0.2, 0.3, 0.2, 0.1 };

        draw2.filledPolygon(x, y);

        // text        draw2.setPenColor(Draw.BLACK);

        draw2.text(0.2, 0.5, “bdfdfdfdlack text”);

        draw2.setPenColor(Draw.WHITE);

        draw2.text(0.8, 0.8, “white text”);

    }

}

/****************************************************************************** *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. * *  This file is part of algs4.jar, which accompanies the textbook * *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. *      http://algs4.cs.princeton.edu * * *  algs4.jar is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  algs4.jar is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with algs4.jar.  If not, see http://www.gnu.org/licenses. ******************************************************************************/

edu/princeton/cs/algs4/DrawListener.java
edu/princeton/cs/algs4/DrawListener.java
/******************************************************************************

 *  Compilation:  javac DrawListener.java

 *  Execution:    none

 *  Dependencies: none

 *

 *  Interface that accompanies Draw.java.

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  DrawListener. This interface provides a basic capability for

 *  responding to keyboard in mouse events from {
@link
 Draw} via callbacks.

 *  You can see some examples in

 *  Section 3.6.

 *

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
interface
 
DrawListener
 
{

    
/**

     * Invoked when the mouse has been pressed.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mousePressed
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been dragged.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseDragged
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been released.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseReleased
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been clicked (pressed and released).

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseClicked
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when a key has been typed.

     *

     * 
@param
 c the character typed

     */

    
void
 keyTyped
(
char
 c
);

    
/**

     * Invoked when a key has been pressed.

     *

     * 
@param
 keycode the key combination pressed

     */

    
void
 keyPressed
(
int
 keycode
);

    
/**

     * Invoked when a key has been released.

     *

     * 
@param
 keycode the key combination released

     */

    
void
 keyReleased
(
int
 keycode
);

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Edge.java
edu/princeton/cs/algs4/Edge.java
/******************************************************************************

 *  Compilation:  javac Edge.java

 *  Execution:    java Edge

 *  Dependencies: StdOut.java

 *

 *  Immutable weighted edge.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Edge} class represents a weighted edge in an 

 *  {
@link
 EdgeWeightedGraph}. Each edge consists of two integers

 *  (naming the two vertices) and a real-value weight. The data type

 *  provides methods for accessing the two endpoints of the edge and

 *  the weight. The natural order for this data type is by

 *  ascending order of weight.

 *  

 *  For additional documentation, see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Edge
 
implements
 
Comparable
< Edge >
 
{
 

    
private
 
final
 
int
 v
;

    
private
 
final
 
int
 w
;

    
private
 
final
 
double
 weight
;

    
/**

     * Initializes an edge between vertices {
@code
 v} and {
@code
 w} of

     * the given {
@code
 weight}.

     *

     * 
@param
  v one vertex

     * 
@param
  w the other vertex

     * 
@param
  weight the weight of this edge

     * 
@throws
 IllegalArgumentException if either {
@code
 v} or {
@code
 w} 

     *         is a negative integer

     * 
@throws
 IllegalArgumentException if {
@code
 weight} is {
@code
 NaN}

     */

    
public
 
Edge
(
int
 v
,
 
int
 w
,
 
double
 weight
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "vertex index must be a nonnegative integer" );          if   ( w  <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a nonnegative integer" );          if   ( Double . isNaN ( weight ))   throw   new   IllegalArgumentException ( "Weight is NaN" );          this . v  =  v ;          this . w  =  w ;          this . weight  =  weight ;      }      /**      * Returns the weight of this edge.      *      *  @return  the weight of this edge      */      public   double  weight ()   {          return  weight ;      }      /**      * Returns either endpoint of this edge.      *      *  @return  either endpoint of this edge      */      public   int  either ()   {          return  v ;      }      /**      * Returns the endpoint of this edge that is different from the given vertex.      *      *  @param   vertex one endpoint of this edge      *  @return  the other endpoint of this edge      *  @throws  IllegalArgumentException if the vertex is not one of the      *         endpoints of this edge      */      public   int  other ( int  vertex )   {          if        ( vertex  ==  v )   return  w ;          else   if   ( vertex  ==  w )   return  v ;          else   throw   new   IllegalArgumentException ( "Illegal endpoint" );      }      /**      * Compares two edges by weight.      * Note that { @code  compareTo()} is not consistent with { @code  equals()},      * which uses the reference equality implementation inherited from { @code  Object}.      *      *  @param   that the other edge      *  @return  a negative integer, zero, or positive integer depending on whether      *         the weight of this is less than, equal to, or greater than the      *         argument edge      */     @ Override      public   int  compareTo ( Edge  that )   {          return   Double . compare ( this . weight ,  that . weight );      }      /**      * Returns a string representation of this edge.      *      *  @return  a string representation of this edge      */      public   String  toString ()   {          return   String . format ( "%d-%d %.5f" ,  v ,  w ,  weight );      }      /**      * Unit tests the { @code  Edge} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          Edge  e  =   new   Edge ( 12 ,   34 ,   5.67 );          StdOut . println ( e );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/EdgeWeightedDigraph.java edu/princeton/cs/algs4/EdgeWeightedDigraph.java /******************************************************************************  *  Compilation:  javac EdgeWeightedDigraph.java  *  Execution:    java EdgeWeightedDigraph digraph.txt  *  Dependencies: Bag.java DirectedEdge.java  *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWD.txt  *                https://algs4.cs.princeton.edu/44sp/mediumEWD.txt  *                https://algs4.cs.princeton.edu/44sp/largeEWD.txt  *  *  An edge-weighted digraph, implemented using adjacency lists.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  EdgeWeightedDigraph} class represents a edge-weighted  *  digraph of vertices named 0 through V – 1, where each

 *  directed edge is of type {
@link
 DirectedEdge} and has a real-valued weight.

 *  It supports the following two primary operations: add a directed edge

 *  to the digraph and iterate over all of edges incident from a given vertex.

 *  It also provides methods for returning the indegree or outdegree of a

 *  vertex, the number of vertices V in the digraph, and

 *  the number of edges E in the digraph.

 *  Parallel edges and self-loops are permitted.

 *  

 *  This implementation uses an adjacency-lists representation, which

 *  is a vertex-indexed array of {
@link
 Bag} objects.

 *  It uses Θ(E + V) space, where E is

 *  the number of edges and V is the number of vertices.

 *  All instance methods take Θ(1) time. (Though, iterating over

 *  the edges returned by {
@link
 #adj(int)} takes time proportional

 *  to the outdegree of the vertex.)

 *  Constructing an empty edge-weighted digraph with V vertices

 *  takes Θ(V) time; constructing an edge-weighted digraph

 *  with E edges and V vertices takes

 *  Θ(E + V) time. 

 *  

 *  For additional documentation,

 *  see Section 4.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
EdgeWeightedDigraph
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;
                
// number of vertices in this digraph

    
private
 
int
 E
;
                      
// number of edges in this digraph

    
private
 
Bag
< DirectedEdge >
[]
 adj
;
    
// adj[v] = adjacency list for vertex v

    
private
 
int
[]
 indegree
;
             
// indegree[v] = indegree of vertex v

    

    
/**

     * Initializes an empty edge-weighted digraph with {
@code
 V} vertices and 0 edges.

     *

     * 
@param
  V the number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   EdgeWeightedDigraph ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;          this . indegree  =   new   int [ V ];         adj  =   ( Bag < DirectedEdge >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             adj [ v ]   =   new   Bag < DirectedEdge >
();

    
}

    
/**

     * Initializes a random edge-weighted digraph with {
@code
 V} vertices and E edges.

     *

     * 
@param
  V the number of vertices

     * 
@param
  E the number of edges

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      *  @throws  IllegalArgumentException if { @code  E < 0}      */      public   EdgeWeightedDigraph ( int  V ,   int  E )   {          this ( V );          if   ( E  <   0 )   throw   new   IllegalArgumentException ( "Number of edges in a Digraph must be nonnegative" );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              double  weight  =   0.01   *   StdRandom . uniform ( 100 );              DirectedEdge  e  =   new   DirectedEdge ( v ,  w ,  weight );             addEdge ( e );          }      }      /**        * Initializes an edge-weighted digraph from the specified input stream.      * The format is the number of vertices V,

     * followed by the number of edges E,

     * followed by E pairs of vertices and edge weights,

     * with each entry separated by whitespace.

     *

     * 
@param
  in the input stream

     * 
@throws
 IllegalArgumentException if {
@code
 in} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if the endpoints of any edge are not in prescribed range

     * 
@throws
 IllegalArgumentException if the number of vertices or edges is negative

     */

    
public
 
EdgeWeightedDigraph
(
In
 in
)
 
{

        
if
 
(
in 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            
this
.

=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Digraph must be nonnegative" );             indegree  =   new   int [ V ];             adj  =   ( Bag < DirectedEdge >
[])
 
new
 
Bag
[
V
];

            
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {                 adj [ v ]   =   new   Bag < DirectedEdge >
();

            
}

            
int
 E 
=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );              for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {                  int  v  =  in . readInt ();                  int  w  =  in . readInt ();                 validateVertex ( v );                 validateVertex ( w );                  double  weight  =  in . readDouble ();                 addEdge ( new   DirectedEdge ( v ,  w ,  weight ));              }          }              catch   ( NoSuchElementException  e )   {              throw   new   IllegalArgumentException ( "invalid input format in EdgeWeightedDigraph constructor" ,  e );          }      }      /**      * Initializes a new edge-weighted digraph that is a deep copy of { @code  G}.      *      *  @param   G the edge-weighted digraph to copy      */      public   EdgeWeightedDigraph ( EdgeWeightedDigraph  G )   {          this ( G . V ());          this . E  =  G . E ();          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              this . indegree [ v ]   =  G . indegree ( v );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              // reverse so that adjacency list is in same order as original              Stack < DirectedEdge >
 reverse 
=
 
new
 
Stack
< DirectedEdge >
();

            
for
 
(
DirectedEdge
 e 
:
 G
.
adj
[
v
])
 
{

                reverse
.
push
(
e
);

            
}

            
for
 
(
DirectedEdge
 e 
:
 reverse
)
 
{

                adj
[
v
].
add
(
e
);

            
}

        
}

    
}

    
/**

     * Returns the number of vertices in this edge-weighted digraph.

     *

     * 
@return
 the number of vertices in this edge-weighted digraph

     */

    
public
 
int
 V
()
 
{

        
return
 V
;

    
}

    
/**

     * Returns the number of edges in this edge-weighted digraph.

     *

     * 
@return
 the number of edges in this edge-weighted digraph

     */

    
public
 
int
 E
()
 
{

        
return
 E
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Adds the directed edge {
@code
 e} to this edge-weighted digraph.

     *

     * 
@param
  e the edge

     * 
@throws
 IllegalArgumentException unless endpoints of edge are between {
@code
 0}

     *         and {
@code
 V-1}

     */

    
public
 
void
 addEdge
(
DirectedEdge
 e
)
 
{

        
int
 v 
=
 e
.
from
();

        
int
 w 
=
 e
.
to
();

        validateVertex
(
v
);

        validateVertex
(
w
);

        adj
[
v
].
add
(
e
);

        indegree
[
w
]
++
;

        E
++
;

    
}

    
/**

     * Returns the directed edges incident from vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the directed edges incident from vertex {
@code
 v} as an Iterable

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   Iterable < DirectedEdge >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 adj
[
v
];

    
}

    
/**

     * Returns the number of directed edges incident from vertex {
@code
 v}.

     * This is known as the outdegree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the outdegree of vertex {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  outdegree ( int  v )   {         validateVertex ( v );          return  adj [ v ]. size ();      }      /**      * Returns the number of directed edges incident to vertex { @code  v}.      * This is known as the indegree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the indegree of vertex {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  indegree ( int  v )   {         validateVertex ( v );          return  indegree [ v ];      }      /**      * Returns all directed edges in this edge-weighted digraph.      * To iterate over the edges in this edge-weighted digraph, use foreach notation:      * { @code  for (DirectedEdge e : G.edges())}.      *      *  @return  all edges in this edge-weighted digraph, as an iterable      */      public   Iterable < DirectedEdge >
 edges
()
 
{

        
Bag
< DirectedEdge >
 list 
=
 
new
 
Bag
< DirectedEdge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              for   ( DirectedEdge  e  :  adj ( v ))   {                 list . add ( e );              }          }          return  list ;      }        /**      * Returns a string representation of this edge-weighted digraph.      *      *  @return  the number of vertices V, followed by the number of edges E,

     *         followed by the V adjacency lists of edges

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” ”
 
+
 E 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( v  +   ": " );              for   ( DirectedEdge  e  :  adj [ v ])   {                 s . append ( e  +   "  " );              }             s . append ( NEWLINE );          }          return  s . toString ();      }      /**      * Unit tests the { @code  EdgeWeightedDigraph} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );          StdOut . println ( G );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.java edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.java /******************************************************************************  *  Compilation:  javac EdgeWeightedDirectedCycle.java  *  Execution:    java EdgeWeightedDirectedCycle V E F  *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Stack.java  *  *  Finds a directed cycle in an edge-weighted digraph.  *  Runs in O(E + V) time.  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  EdgeWeightedDirectedCycle} class represents a data type for   *  determining whether an edge-weighted digraph has a directed cycle.  *  The hasCycle operation determines whether the edge-weighted

 *  digraph has a directed cycle and, if so, the cycle operation

 *  returns one.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the 

 *  edge-weighted digraph).

 *  

 *  See {
@link
 Topological} to compute a topological order if the

 *  edge-weighted digraph is acyclic.

 *  

 *  For additional documentation,   

 *  see Section 4.4 of   

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
EdgeWeightedDirectedCycle
 
{

    
private
 
boolean
[]
 marked
;
             
// marked[v] = has vertex v been marked?

    
private
 
DirectedEdge
[]
 edgeTo
;
        
// edgeTo[v] = previous edge on path to v

    
private
 
boolean
[]
 onStack
;
            
// onStack[v] = is vertex on the stack?

    
private
 
Stack
< DirectedEdge >
 cycle
;
    
// directed cycle (or null if no such cycle)

    
/**

     * Determines whether the edge-weighted digraph {
@code
 G} has a directed cycle and,

     * if so, finds such a cycle.

     * 
@param
 G the edge-weighted digraph

     */

    
public
 
EdgeWeightedDirectedCycle
(
EdgeWeightedDigraph
 G
)
 
{

        marked  
=
 
new
 
boolean
[
G
.
V
()];

        onStack 
=
 
new
 
boolean
[
G
.
V
()];

        edgeTo  
=
 
new
 
DirectedEdge
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( ! marked [ v ])  dfs ( G ,  v );          // check that digraph has a cycle          assert  check ();      }      // check that algorithm computes either the topological order or finds a directed cycle      private   void  dfs ( EdgeWeightedDigraph  G ,   int  v )   {         onStack [ v ]   =   true ;         marked [ v ]   =   true ;          for   ( DirectedEdge  e  :  G . adj ( v ))   {              int  w  =  e . to ();              // short circuit if directed cycle found              if   ( cycle  !=   null )   return ;              // found new vertex, so recur              else   if   ( ! marked [ w ])   {                 edgeTo [ w ]   =  e ;                 dfs ( G ,  w );              }              // trace back directed cycle              else   if   ( onStack [ w ])   {                 cycle  =   new   Stack < DirectedEdge >
();

                
DirectedEdge
 f 
=
 e
;

                
while
 
(
f
.
from
()
 
!=
 w
)
 
{

                    cycle
.
push
(
f
);

                    f 
=
 edgeTo
[
f
.
from
()];

                
}

                cycle
.
push
(
f
);

                
return
;

            
}

        
}

        onStack
[
v
]
 
=
 
false
;

    
}

    
/**

     * Does the edge-weighted digraph have a directed cycle?

     * 
@return
 {
@code
 true} if the edge-weighted digraph has a directed cycle,

     * {
@code
 false} otherwise

     */

    
public
 
boolean
 hasCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
/**

     * Returns a directed cycle if the edge-weighted digraph has a directed cycle,

     * and {
@code
 null} otherwise.

     * 
@return
 a directed cycle (as an iterable) if the edge-weighted digraph

     *    has a directed cycle, and {
@code
 null} otherwise

     */

    
public
 
Iterable
< DirectedEdge >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
// certify that digraph is either acyclic or has a directed cycle

    
private
 
boolean
 check
()
 
{

        
// edge-weighted digraph is cyclic

        
if
 
(
hasCycle
())
 
{

            
// verify cycle

            
DirectedEdge
 first 
=
 
null
,
 last 
=
 
null
;

            
for
 
(
DirectedEdge
 e 
:
 cycle
())
 
{

                
if
 
(
first 
==
 
null
)
 first 
=
 e
;

                
if
 
(
last 
!=
 
null
)
 
{

                    
if
 
(
last
.
to
()
 
!=
 e
.
from
())
 
{

                        
System
.
err
.
printf
(
“cycle edges %s and %s not incident\n”
,
 last
,
 e
);

                        
return
 
false
;

                    
}

                
}

                last 
=
 e
;

            
}

            
if
 
(
last
.
to
()
 
!=
 first
.
from
())
 
{

                
System
.
err
.
printf
(
“cycle edges %s and %s not incident\n”
,
 last
,
 first
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
/**

     * Unit tests the {
@code
 EdgeWeightedDirectedCycle} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// create random DAG with V vertices and E edges; then add F random edges

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 F 
=
 
Integer
.
parseInt
(
args
[
2
]);

        
EdgeWeightedDigraph
 G 
=
 
new
 
EdgeWeightedDigraph
(
V
);

        
int
[]
 vertices 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {              int  v ,  w ;              do   {                 v  =   StdRandom . uniform ( V );                 w  =   StdRandom . uniform ( V );              }   while   ( v  >=
 w
);

            
double
 weight 
=
 
StdRandom
.
uniform
();

            G
.
addEdge
(
new
 
DirectedEdge
(
v
,
 w
,
 weight
));

        
}

        
// add F extra edges

        
for
 
(
int
 i 
=
 
0
;
 i 
<  F ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              double  weight  =   StdRandom . uniform ( 0.0 ,   1.0 );             G . addEdge ( new   DirectedEdge ( v ,  w ,  weight ));          }          StdOut . println ( G );          // find a directed cycle          EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( G );          if   ( finder . hasCycle ())   {              StdOut . print ( "Cycle: " );              for   ( DirectedEdge  e  :  finder . cycle ())   {                  StdOut . print ( e  +   " " );              }              StdOut . println ();          }          // or give topologial sort          else   {              StdOut . println ( "No directed cycle" );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/EdgeWeightedGraph.java edu/princeton/cs/algs4/EdgeWeightedGraph.java /******************************************************************************  *  Compilation:  javac EdgeWeightedGraph.java  *  Execution:    java EdgeWeightedGraph filename.txt  *  Dependencies: Bag.java Edge.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt  *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt  *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt  *  *  An edge-weighted undirected graph, implemented using adjacency lists.  *  Parallel edges and self-loops are permitted.  *  *  % java EdgeWeightedGraph tinyEWG.txt   *  8 16  *  0: 6-0 0.58000  0-2 0.26000  0-4 0.38000  0-7 0.16000    *  1: 1-3 0.29000  1-2 0.36000  1-7 0.19000  1-5 0.32000    *  2: 6-2 0.40000  2-7 0.34000  1-2 0.36000  0-2 0.26000  2-3 0.17000    *  3: 3-6 0.52000  1-3 0.29000  2-3 0.17000    *  4: 6-4 0.93000  0-4 0.38000  4-7 0.37000  4-5 0.35000    *  5: 1-5 0.32000  5-7 0.28000  4-5 0.35000    *  6: 6-4 0.93000  6-0 0.58000  3-6 0.52000  6-2 0.40000  *  7: 2-7 0.34000  1-7 0.19000  0-7 0.16000  5-7 0.28000  4-7 0.37000  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  EdgeWeightedGraph} class represents an edge-weighted  *  graph of vertices named 0 through V – 1, where each

 *  undirected edge is of type {
@link
 Edge} and has a real-valued weight.

 *  It supports the following two primary operations: add an edge to the graph,

 *  iterate over all of the edges incident to a vertex. It also provides

 *  methods for returning the degree of a vertex, the number of vertices

 *  V in the graph, and the number of edges E in the graph.

 *  Parallel edges and self-loops are permitted.

 *  By convention, a self-loop vv appears in the

 *  adjacency list of v twice and contributes two to the degree

 *  of v.

 *  

 *  This implementation uses an adjacency-lists representation, which

 *  is a vertex-indexed array of {
@link
 Bag} objects.

 *  It uses Θ(E + V) space, where E is

 *  the number of edges and V is the number of vertices.

 *  All instance methods take Θ(1) time. (Though, iterating over

 *  the edges returned by {
@link
 #adj(int)} takes time proportional

 *  to the degree of the vertex.)

 *  Constructing an empty edge-weighted graph with V vertices takes

 *  Θ(V) time; constructing a edge-weighted graph with

 *  E edges and V vertices takes

 *  Θ(E + V) time. 

 *  

 *  For additional documentation,

 *  see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
EdgeWeightedGraph
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;

    
private
 
int
 E
;

    
private
 
Bag
< Edge >
[]
 adj
;

    

    
/**

     * Initializes an empty edge-weighted graph with {
@code
 V} vertices and 0 edges.

     *

     * 
@param
  V the number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   EdgeWeightedGraph ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;         adj  =   ( Bag < Edge >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             adj [ v ]   =   new   Bag < Edge >
();

        
}

    
}

    
/**

     * Initializes a random edge-weighted graph with {
@code
 V} vertices and E edges.

     *

     * 
@param
  V the number of vertices

     * 
@param
  E the number of edges

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      *  @throws  IllegalArgumentException if { @code  E < 0}      */      public   EdgeWeightedGraph ( int  V ,   int  E )   {          this ( V );          if   ( E  <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              double  weight  =   Math . round ( 100   *   StdRandom . uniform ())   /   100.0 ;              Edge  e  =   new   Edge ( v ,  w ,  weight );             addEdge ( e );          }      }      /**        * Initializes an edge-weighted graph from an input stream.      * The format is the number of vertices V,

     * followed by the number of edges E,

     * followed by E pairs of vertices and edge weights,

     * with each entry separated by whitespace.

     *

     * 
@param
  in the input stream

     * 
@throws
 IllegalArgumentException if {
@code
 in} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if the endpoints of any edge are not in prescribed range

     * 
@throws
 IllegalArgumentException if the number of vertices or edges is negative

     */

    
public
 
EdgeWeightedGraph
(
In
 in
)
 
{

        
if
 
(
in 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            V 
=
 in
.
readInt
();

            adj 
=
 
(
Bag
< Edge >
[])
 
new
 
Bag
[
V
];

            
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {                 adj [ v ]   =   new   Bag < Edge >
();

            
}

            
int
 E 
=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );              for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {                  int  v  =  in . readInt ();                  int  w  =  in . readInt ();                 validateVertex ( v );                 validateVertex ( w );                  double  weight  =  in . readDouble ();                  Edge  e  =   new   Edge ( v ,  w ,  weight );                 addEdge ( e );              }          }              catch   ( NoSuchElementException  e )   {              throw   new   IllegalArgumentException ( "invalid input format in EdgeWeightedGraph constructor" ,  e );          }      }      /**      * Initializes a new edge-weighted graph that is a deep copy of { @code  G}.      *      *  @param   G the edge-weighted graph to copy      */      public   EdgeWeightedGraph ( EdgeWeightedGraph  G )   {          this ( G . V ());          this . E  =  G . E ();          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              // reverse so that adjacency list is in same order as original              Stack < Edge >
 reverse 
=
 
new
 
Stack
< Edge >
();

            
for
 
(
Edge
 e 
:
 G
.
adj
[
v
])
 
{

                reverse
.
push
(
e
);

            
}

            
for
 
(
Edge
 e 
:
 reverse
)
 
{

                adj
[
v
].
add
(
e
);

            
}

        
}

    
}

    
/**

     * Returns the number of vertices in this edge-weighted graph.

     *

     * 
@return
 the number of vertices in this edge-weighted graph

     */

    
public
 
int
 V
()
 
{

        
return
 V
;

    
}

    
/**

     * Returns the number of edges in this edge-weighted graph.

     *

     * 
@return
 the number of edges in this edge-weighted graph

     */

    
public
 
int
 E
()
 
{

        
return
 E
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Adds the undirected edge {
@code
 e} to this edge-weighted graph.

     *

     * 
@param
  e the edge

     * 
@throws
 IllegalArgumentException unless both endpoints are between {
@code
 0} and {
@code
 V-1}

     */

    
public
 
void
 addEdge
(
Edge
 e
)
 
{

        
int
 v 
=
 e
.
either
();

        
int
 w 
=
 e
.
other
(
v
);

        validateVertex
(
v
);

        validateVertex
(
w
);

        adj
[
v
].
add
(
e
);

        adj
[
w
].
add
(
e
);

        E
++
;

    
}

    
/**

     * Returns the edges incident on vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the edges incident on vertex {
@code
 v} as an Iterable

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   Iterable < Edge >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 adj
[
v
];

    
}

    
/**

     * Returns the degree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the degree of vertex {
@code
 v}               

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  degree ( int  v )   {         validateVertex ( v );          return  adj [ v ]. size ();      }      /**      * Returns all edges in this edge-weighted graph.      * To iterate over the edges in this edge-weighted graph, use foreach notation:      * { @code  for (Edge e : G.edges())}.      *      *  @return  all edges in this edge-weighted graph, as an iterable      */      public   Iterable < Edge >
 edges
()
 
{

        
Bag
< Edge >
 list 
=
 
new
 
Bag
< Edge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              int  selfLoops  =   0 ;              for   ( Edge  e  :  adj ( v ))   {                  if   ( e . other ( v )   >
 v
)
 
{

                    list
.
add
(
e
);

                
}

                
// add only one copy of each self loop (self loops will be consecutive)

                
else
 
if
 
(
e
.
other
(
v
)
 
==
 v
)
 
{

                    
if
 
(
selfLoops 
%
 
2
 
==
 
0
)
 list
.
add
(
e
);

                    selfLoops
++
;

                
}

            
}

        
}

        
return
 list
;

    
}

    
/**

     * Returns a string representation of the edge-weighted graph.

     * This method takes time proportional to E + V.

     *

     * 
@return
 the number of vertices V, followed by the number of edges E,

     *         followed by the V adjacency lists of edges

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” ”
 
+
 E 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( v  +   ": " );              for   ( Edge  e  :  adj [ v ])   {                 s . append ( e  +   "  " );              }             s . append ( NEWLINE );          }          return  s . toString ();      }      /**      * Unit tests the { @code  EdgeWeightedGraph} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );          StdOut . println ( G );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/EulerianCycle.java edu/princeton/cs/algs4/EulerianCycle.java /******************************************************************************  *  Compilation:  javac EulerianCycle.java  *  Execution:    java  EulerianCycle V E  *  Dependencies: Graph.java Stack.java StdOut.java  *  *  Find an Eulerian cycle in a graph, if one exists.  *  *  Runs in O(E + V) time.  *  *  This implementation is tricker than the one for digraphs because  *  when we use edge v-w from v's adjacency list, we must be careful  *  not to use the second copy of the edge from w's adjaceny list.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  EulerianCycle} class represents a data type  *  for finding an Eulerian cycle or path in a graph.  *  An Eulerian cycle is a cycle (not necessarily simple) that

 *  uses every edge in the graph exactly once.

 *  

 *  This implementation uses a nonrecursive depth-first search.

 *  The constructor takes Θ(E + V) time in the worst

 *  case, where E is the number of edges and V is the

 *  number of vertices

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(E + V) extra space in the worst case

 *  (not including the graph).

 *  

 *  To compute Eulerian paths in graphs, see {
@link
 EulerianPath}.

 *  To compute Eulerian cycles and paths in digraphs, see

 *  {
@link
 DirectedEulerianCycle} and {
@link
 DirectedEulerianPath}.

 *  

 *  For additional documentation,

 *  see Section 4.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 * 

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 Nate Liu

 */

public
 
class
 
EulerianCycle
 
{

    
private
 
Stack
< Integer >
 cycle 
=
 
new
 
Stack
< Integer >
();
  
// Eulerian cycle; null if no such cycle

    
// an undirected edge, with a field to indicate whether the edge has already been used

    
private
 
static
 
class
 
Edge
 
{

        
private
 
final
 
int
 v
;

        
private
 
final
 
int
 w
;

        
private
 
boolean
 isUsed
;

        
public
 
Edge
(
int
 v
,
 
int
 w
)
 
{

            
this
.

=
 v
;

            
this
.

=
 w
;

            isUsed 
=
 
false
;

        
}

        
// returns the other vertex of the edge

        
public
 
int
 other
(
int
 vertex
)
 
{

            
if
      
(
vertex 
==
 v
)
 
return
 w
;

            
else
 
if
 
(
vertex 
==
 w
)
 
return
 v
;

            
else
 
throw
 
new
 
IllegalArgumentException
(
“Illegal endpoint”
);

        
}

    
}

    
/**

     * Computes an Eulerian cycle in the specified graph, if one exists.

     * 

     * 
@param
 G the graph

     */

    
public
 
EulerianCycle
(
Graph
 G
)
 
{

        
// must have at least one edge

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
;

        
// necessary condition: all vertices have even degree

        
// (this test is needed or it might find an Eulerian path instead of cycle)

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )                if   ( G . degree ( v )   %   2   !=   0 )                  return ;          // create local view of adjacency lists, to iterate one vertex at a time          // the helper Edge data type is used to avoid exploring both copies of an edge v-w          Queue < Edge >
[]
 adj 
=
 
(
Queue
< Edge >
[])
 
new
 
Queue
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =   new   Queue < Edge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              int  selfLoops  =   0 ;              for   ( int  w  :  G . adj ( v ))   {                  // careful with self loops                  if   ( v  ==  w )   {                      if   ( selfLoops  %   2   ==   0 )   {                          Edge  e  =   new   Edge ( v ,  w );                         adj [ v ]. enqueue ( e );                         adj [ w ]. enqueue ( e );                      }                     selfLoops ++ ;                  }                  else   if   ( v  <  w )   {                      Edge  e  =   new   Edge ( v ,  w );                     adj [ v ]. enqueue ( e );                     adj [ w ]. enqueue ( e );                  }              }          }          // initialize stack with any non-isolated vertex          int  s  =  nonIsolatedVertex ( G );          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        stack
.
push
(
s
);

        
// greedily search through edges in iterative DFS style

        cycle 
=
 
new
 
Stack
< Integer >
();

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
pop
();

            
while
 
(
!
adj
[
v
].
isEmpty
())
 
{

                
Edge
 edge 
=
 adj
[
v
].
dequeue
();

                
if
 
(
edge
.
isUsed
)
 
continue
;

                edge
.
isUsed 
=
 
true
;

                stack
.
push
(
v
);

                v 
=
 edge
.
other
(
v
);

            
}

            
// push vertex with no more leaving edges to cycle

            cycle
.
push
(
v
);

        
}

        
// check if all edges are used

        
if
 
(
cycle
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)

            cycle 
=
 
null
;

        
assert
 certifySolution
(
G
);

    
}

    
/**

     * Returns the sequence of vertices on an Eulerian cycle.

     * 

     * 
@return
 the sequence of vertices on an Eulerian cycle;

     *         {
@code
 null} if no such cycle

     */

    
public
 
Iterable
< Integer >
 cycle
()
 
{

        
return
 cycle
;

    
}

    
/**

     * Returns true if the graph has an Eulerian cycle.

     * 

     * 
@return
 {
@code
 true} if the graph has an Eulerian cycle;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasEulerianCycle
()
 
{

        
return
 cycle 
!=
 
null
;

    
}

    
// returns any non-isolated vertex; -1 if no such vertex

    
private
 
static
 
int
 nonIsolatedVertex
(
Graph
 G
)
 
{

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . degree ( v )   >
 
0
)

                
return
 v
;

        
return
 

1
;

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// Determines whether a graph has an Eulerian cycle using necessary

    
// and sufficient conditions (without computing the cycle itself):

    
//    – at least one edge

    
//    – degree(v) is even for every vertex v

    
//    – the graph is connected (ignoring isolated vertices)

    
private
 
static
 
boolean
 satisfiesNecessaryAndSufficientConditions
(
Graph
 G
)
 
{

        
// Condition 0: at least 1 edge

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
 
false
;

        
// Condition 1: degree(v) is even for every vertex

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . degree ( v )   %   2   !=   0 )                  return   false ;          // Condition 2: graph is connected, ignoring isolated vertices          int  s  =  nonIsolatedVertex ( G );          BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( G ,  s );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              if   ( G . degree ( v )   >
 
0
 
&&
 
!
bfs
.
hasPathTo
(
v
))

                
return
 
false
;

        
return
 
true
;

    
}

    
// check that solution is correct

    
private
 
boolean
 certifySolution
(
Graph
 G
)
 
{

        
// internal consistency check

        
if
 
(
hasEulerianCycle
()
 
==
 
(
cycle
()
 
==
 
null
))
 
return
 
false
;

        
// hashEulerianCycle() returns correct value

        
if
 
(
hasEulerianCycle
()
 
!=
 satisfiesNecessaryAndSufficientConditions
(
G
))
 
return
 
false
;

        
// nothing else to check if no Eulerian cycle

        
if
 
(
cycle 
==
 
null
)
 
return
 
true
;

        
// check that cycle() uses correct number of edges

        
if
 
(
cycle
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)
 
return
 
false
;

        
// check that cycle() is a cycle of G

        
// TODO

        
// check that first and last vertices in cycle() are the same

        
int
 first 
=
 

1
,
 last 
=
 

1
;

        
for
 
(
int
 v 
:
 cycle
())
 
{

            
if
 
(
first 
==
 

1
)
 first 
=
 v
;

            last 
=
 v
;

        
}

        
if
 
(
first 
!=
 last
)
 
return
 
false
;

        
return
 
true
;

    
}

    
private
 
static
 
void
 unitTest
(
Graph
 G
,
 
String
 description
)
 
{

        
StdOut
.
println
(
description
);

        
StdOut
.
println
(
“————————————-”
);

        
StdOut
.
print
(
G
);

        
EulerianCycle
 euler 
=
 
new
 
EulerianCycle
(
G
);

        
StdOut
.
print
(
“Eulerian cycle: ”
);

        
if
 
(
euler
.
hasEulerianCycle
())
 
{

            
for
 
(
int
 v 
:
 euler
.
cycle
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“none”
);

        
}

        
StdOut
.
println
();

    
}

    
/**

     * Unit tests the {
@code
 EulerianCycle} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// Eulerian cycle

        
Graph
 G1 
=
 
GraphGenerator
.
eulerianCycle
(
V
,
 E
);

        unitTest
(
G1
,
 
“Eulerian cycle”
);

        
// Eulerian path

        
Graph
 G2 
=
 
GraphGenerator
.
eulerianPath
(
V
,
 E
);

        unitTest
(
G2
,
 
“Eulerian path”
);

        
// empty graph

        
Graph
 G3 
=
 
new
 
Graph
(
V
);

        unitTest
(
G3
,
 
“empty graph”
);

        
// self loop

        
Graph
 G4 
=
 
new
 
Graph
(
V
);

        
int
 v4 
=
 
StdRandom
.
uniform
(
V
);

        G4
.
addEdge
(
v4
,
 v4
);

        unitTest
(
G4
,
 
“single self loop”
);

        
// union of two disjoint cycles

        
Graph
 H1 
=
 
GraphGenerator
.
eulerianCycle
(
V
/
2
,
 E
/
2
);

        
Graph
 H2 
=
 
GraphGenerator
.
eulerianCycle
(


 V
/
2
,
 E 

 E
/
2
);

        
int
[]
 perm 
=
 
new
 
int
[
V
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )             perm [ i ]   =  i ;          StdRandom . shuffle ( perm );          Graph  G5  =   new   Graph ( V );          for   ( int  v  =   0 ;  v  <  H1 . V ();  v ++ )              for   ( int  w  :  H1 . adj ( v ))                 G5 . addEdge ( perm [ v ],  perm [ w ]);          for   ( int  v  =   0 ;  v  <  H2 . V ();  v ++ )              for   ( int  w  :  H2 . adj ( v ))                 G5 . addEdge ( perm [ V / 2   +  v ],  perm [ V / 2   +  w ]);         unitTest ( G5 ,   "Union of two disjoint cycles" );          // random digraph          Graph  G6  =   GraphGenerator . simple ( V ,  E );         unitTest ( G6 ,   "simple graph" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/EulerianPath.java edu/princeton/cs/algs4/EulerianPath.java /******************************************************************************  *  Compilation:  javac EulerianPath.java  *  Execution:    java EulerianPath V E  *  Dependencies: Graph.java Stack.java StdOut.java  *  *  Find an Eulerian path in a graph, if one exists.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  EulerianPath} class represents a data type  *  for finding an Eulerian path in a graph.  *  An Eulerian path is a path (not necessarily simple) that

 *  uses every edge in the graph exactly once.

 *  

 *  This implementation uses a nonrecursive depth-first search.

 *  The constructor takes Θ(E + V) time in the worst

 *  case, where E is the number of edges and V is

 *  the number of vertices.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(E + V) extra space in the worst case

 *  (not including the digraph).

 *  

 *  To compute Eulerian cycles in graphs, see {
@link
 EulerianCycle}.

 *  To compute Eulerian cycles and paths in digraphs, see

 *  {
@link
 DirectedEulerianCycle} and {
@link
 DirectedEulerianPath}.

 *  

 *  For additional documentation,

 *  see Section 4.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 * 

 * 
@author
 Robert Sedgewick

 * 
@author
 Kevin Wayne

 * 
@author
 Nate Liu

 */

public
 
class
 
EulerianPath
 
{

    
private
 
Stack
< Integer >
 path 
=
 
null
;
   
// Eulerian path; null if no suh path

    
// an undirected edge, with a field to indicate whether the edge has already been used

    
private
 
static
 
class
 
Edge
 
{

        
private
 
final
 
int
 v
;

        
private
 
final
 
int
 w
;

        
private
 
boolean
 isUsed
;

        
public
 
Edge
(
int
 v
,
 
int
 w
)
 
{

            
this
.

=
 v
;

            
this
.

=
 w
;

            isUsed 
=
 
false
;

        
}

        
// returns the other vertex of the edge

        
public
 
int
 other
(
int
 vertex
)
 
{

            
if
      
(
vertex 
==
 v
)
 
return
 w
;

            
else
 
if
 
(
vertex 
==
 w
)
 
return
 v
;

            
else
 
throw
 
new
 
IllegalArgumentException
(
“Illegal endpoint”
);

        
}

    
}

    
/**

     * Computes an Eulerian path in the specified graph, if one exists.

     * 

     * 
@param
 G the graph

     */

    
public
 
EulerianPath
(
Graph
 G
)
 
{

        
// find vertex from which to start potential Eulerian path:

        
// a vertex v with odd degree(v) if it exits;

        
// otherwise a vertex with degree(v) > 0

        
int
 oddDegreeVertices 
=
 
0
;

        
int
 s 
=
 nonIsolatedVertex
(
G
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( G . degree ( v )   %   2   !=   0 )   {                 oddDegreeVertices ++ ;                 s  =  v ;              }          }          // graph can't have an Eulerian path          // (this condition is needed for correctness)          if   ( oddDegreeVertices  >
 
2
)
 
return
;

        
// special case for graph with zero edges (has a degenerate Eulerian path)

        
if
 
(

==
 

1
)
 s 
=
 
0
;

        
// create local view of adjacency lists, to iterate one vertex at a time

        
// the helper Edge data type is used to avoid exploring both copies of an edge v-w

        
Queue
< Edge >
[]
 adj 
=
 
(
Queue
< Edge >
[])
 
new
 
Queue
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =   new   Queue < Edge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              int  selfLoops  =   0 ;              for   ( int  w  :  G . adj ( v ))   {                  // careful with self loops                  if   ( v  ==  w )   {                      if   ( selfLoops  %   2   ==   0 )   {                          Edge  e  =   new   Edge ( v ,  w );                         adj [ v ]. enqueue ( e );                         adj [ w ]. enqueue ( e );                      }                     selfLoops ++ ;                  }                  else   if   ( v  <  w )   {                      Edge  e  =   new   Edge ( v ,  w );                     adj [ v ]. enqueue ( e );                     adj [ w ]. enqueue ( e );                  }              }          }          // initialize stack with any non-isolated vertex          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        stack
.
push
(
s
);

        
// greedily search through edges in iterative DFS style

        path 
=
 
new
 
Stack
< Integer >
();

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
pop
();

            
while
 
(
!
adj
[
v
].
isEmpty
())
 
{

                
Edge
 edge 
=
 adj
[
v
].
dequeue
();

                
if
 
(
edge
.
isUsed
)
 
continue
;

                edge
.
isUsed 
=
 
true
;

                stack
.
push
(
v
);

                v 
=
 edge
.
other
(
v
);

            
}

            
// push vertex with no more leaving edges to path

            path
.
push
(
v
);

        
}

        
// check if all edges are used

        
if
 
(
path
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)

            path 
=
 
null
;

        
assert
 certifySolution
(
G
);

    
}

    
/**

     * Returns the sequence of vertices on an Eulerian path.

     * 

     * 
@return
 the sequence of vertices on an Eulerian path;

     *         {
@code
 null} if no such path

     */

    
public
 
Iterable
< Integer >
 path
()
 
{

        
return
 path
;

    
}

    
/**

     * Returns true if the graph has an Eulerian path.

     * 

     * 
@return
 {
@code
 true} if the graph has an Eulerian path;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasEulerianPath
()
 
{

        
return
 path 
!=
 
null
;

    
}

    
// returns any non-isolated vertex; -1 if no such vertex

    
private
 
static
 
int
 nonIsolatedVertex
(
Graph
 G
)
 
{

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . degree ( v )   >
 
0
)

                
return
 v
;

        
return
 

1
;

    
}

    
/**************************************************************************

     *

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// Determines whether a graph has an Eulerian path using necessary

    
// and sufficient conditions (without computing the path itself):

    
//    – degree(v) is even for every vertex, except for possibly two

    
//    – the graph is connected (ignoring isolated vertices)

    
// This method is solely for unit testing.

    
private
 
static
 
boolean
 satisfiesNecessaryAndSufficientConditions
(
Graph
 G
)
 
{

        
if
 
(
G
.
E
()
 
==
 
0
)
 
return
 
true
;

        
// Condition 1: degree(v) is even except for possibly two

        
int
 oddDegreeVertices 
=
 
0
;

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . degree ( v )   %   2   !=   0 )                 oddDegreeVertices ++ ;          if   ( oddDegreeVertices  >
 
2
)
 
return
 
false
;

        
// Condition 2: graph is connected, ignoring isolated vertices

        
int
 s 
=
 nonIsolatedVertex
(
G
);

        
BreadthFirstPaths
 bfs 
=
 
new
 
BreadthFirstPaths
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( G . degree ( v )   >
 
0
 
&&
 
!
bfs
.
hasPathTo
(
v
))

                
return
 
false
;

        
return
 
true
;

    
}

    
// check that solution is correct

    
private
 
boolean
 certifySolution
(
Graph
 G
)
 
{

        
// internal consistency check

        
if
 
(
hasEulerianPath
()
 
==
 
(
path
()
 
==
 
null
))
 
return
 
false
;

        
// hashEulerianPath() returns correct value

        
if
 
(
hasEulerianPath
()
 
!=
 satisfiesNecessaryAndSufficientConditions
(
G
))
 
return
 
false
;

        
// nothing else to check if no Eulerian path

        
if
 
(
path 
==
 
null
)
 
return
 
true
;

        
// check that path() uses correct number of edges

        
if
 
(
path
.
size
()
 
!=
 G
.
E
()
 
+
 
1
)
 
return
 
false
;

        
// check that path() is a path in G

        
// TODO

        
return
 
true
;

    
}

    
private
 
static
 
void
 unitTest
(
Graph
 G
,
 
String
 description
)
 
{

        
StdOut
.
println
(
description
);

        
StdOut
.
println
(
“————————————-”
);

        
StdOut
.
print
(
G
);

        
EulerianPath
 euler 
=
 
new
 
EulerianPath
(
G
);

        
StdOut
.
print
(
“Eulerian path:  ”
);

        
if
 
(
euler
.
hasEulerianPath
())
 
{

            
for
 
(
int
 v 
:
 euler
.
path
())
 
{

                
StdOut
.
print
(

+
 
” ”
);

            
}

            
StdOut
.
println
();

        
}

        
else
 
{

            
StdOut
.
println
(
“none”
);

        
}

        
StdOut
.
println
();

    
}

    
/**

     * Unit tests the {
@code
 EulerianPath} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// Eulerian cycle

        
Graph
 G1 
=
 
GraphGenerator
.
eulerianCycle
(
V
,
 E
);

        unitTest
(
G1
,
 
“Eulerian cycle”
);

        
// Eulerian path

        
Graph
 G2 
=
 
GraphGenerator
.
eulerianPath
(
V
,
 E
);

        unitTest
(
G2
,
 
“Eulerian path”
);

        
// add one random edge

        
Graph
 G3 
=
 
new
 
Graph
(
G2
);

        G3
.
addEdge
(
StdRandom
.
uniform
(
V
),
 
StdRandom
.
uniform
(
V
));

        unitTest
(
G3
,
 
“one random edge added to Eulerian path”
);

        
// self loop

        
Graph
 G4 
=
 
new
 
Graph
(
V
);

        
int
 v4 
=
 
StdRandom
.
uniform
(
V
);

        G4
.
addEdge
(
v4
,
 v4
);

        unitTest
(
G4
,
 
“single self loop”
);

        
// single edge

        
Graph
 G5 
=
 
new
 
Graph
(
V
);

        G5
.
addEdge
(
StdRandom
.
uniform
(
V
),
 
StdRandom
.
uniform
(
V
));

        unitTest
(
G5
,
 
“single edge”
);

        
// empty graph

        
Graph
 G6 
=
 
new
 
Graph
(
V
);

        unitTest
(
G6
,
 
“empty graph”
);

        
// random graph

        
Graph
 G7 
=
 
GraphGenerator
.
simple
(
V
,
 E
);

        unitTest
(
G7
,
 
“simple graph”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/FarthestPair.java
edu/princeton/cs/algs4/FarthestPair.java
/******************************************************************************

 *  Compilation:  javac FarthestPair.java

 *  Execution:    java FarthestPair < input.txt  *  Dependencies: GrahamScan.java Point2D.java  *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt  *                https://algs4.cs.princeton.edu/99hull/kw1260.txt  *    *  Given a set of n points in the plane, find the farthest pair  *  (equivalently, compute the diameter of the set of points).  *  *  Computes the convex hull of the set of points and using the  *  rotating calipers method to find all antipodal point pairs  *  and the farthest pair.  *  *  % java FarthestPair < input100.txt  *  42697.98170874122 from (32011.0, 3140.0) to (822.0, 32301.0)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  FarthestPair} data type computes the farthest pair of points  *  in a set of n points in the plane and provides accessor methods

 *  for getting the farthest pair of points and the distance between them.

 *  The distance between two points is their Euclidean distance.

 *  

 *  This implementation computes the convex hull of the set of points and

 *  uses the rotating calipers method to find all antipodal point pairs

 *  and the farthest pair.

 *  It runs in O(n log n) time in the worst case and uses

 *  O(N) extra space.

 *  See also {
@link
 ClosestPair} and {
@link
 GrahamScan}.

 *  

 *  For additional documentation, see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FarthestPair
 
{

    
// farthest pair of points and distance

    
private
 
Point2D
 best1
,
 best2
;

    
private
 
double
 bestDistanceSquared 
=
 
Double
.
NEGATIVE_INFINITY
;

    
/**

     * Computes the farthest pair of points in the specified array of points.

     *

     * 
@param
  points the array of points

     * 
@throws
 IllegalArgumentException if {
@code
 points} is {
@code
 null} or if any

     *         entry in {
@code
 points[]} is {
@code
 null}

     */

    
public
 
FarthestPair
(
Point2D
[]
 points
)
 
{

        
if
 
(
points 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“constructor argument is null”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  points . length ;  i ++ )   {              if   ( points [ i ]   ==   null )   throw   new   IllegalArgumentException ( "array element "   +  i  +   " is null" );          }          GrahamScan  graham  =   new   GrahamScan ( points );          // single point          if   ( points . length  <=   1 )   return ;          // number of points on the hull          int  m  =   0 ;          for   ( Point2D  p  :  graham . hull ())             m ++ ;          // the hull, in counterclockwise order hull[1] to hull[m]          Point2D []  hull  =   new   Point2D [ m + 1 ];         m  =   1 ;          for   ( Point2D  p  :  graham . hull ())   {             hull [ m ++ ]   =  p ;          }         m -- ;          // all points are equal          if   ( m  ==   1 )   return ;          // points are collinear          if   ( m  ==   2 )   {             best1  =  hull [ 1 ];             best2  =  hull [ 2 ];             bestDistanceSquared  =  best1 . distanceSquaredTo ( best2 );              return ;          }          // k = farthest vertex from edge from hull[1] to hull[m]          int  k  =   2 ;          while   ( Point2D . area2 ( hull [ m ],  hull [ 1 ],  hull [ k + 1 ])   >
 
Point2D
.
area2
(
hull
[
m
],
 hull
[
1
],
 hull
[
k
]))
 
{

            k
++
;

        
}

        
int
 j 
=
 k
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  k  &&  j  <=  m ;  i ++ )   {              // StdOut.println("hull[i] + " and " + hull[j] + " are antipodal");              if   ( hull [ i ]. distanceSquaredTo ( hull [ j ])   >
 bestDistanceSquared
)
 
{

                best1 
=
 hull
[
i
];

                best2 
=
 hull
[
j
];

                bestDistanceSquared 
=
 hull
[
i
].
distanceSquaredTo
(
hull
[
j
]);

            
}

            
while
 
((

<  m )   &&   Point2D . area2 ( hull [ i ],  hull [ i + 1 ],  hull [ j + 1 ])   >
 
Point2D
.
area2
(
hull
[
i
],
 hull
[
i
+
1
],
 hull
[
j
]))
 
{

                j
++
;

                
// StdOut.println(hull[i] + ” and ” + hull[j] + ” are antipodal”);

                
double
 distanceSquared 
=
 hull
[
i
].
distanceSquaredTo
(
hull
[
j
]);

                
if
 
(
distanceSquared 
>
 bestDistanceSquared
)
 
{

                    best1 
=
 hull
[
i
];

                    best2 
=
 hull
[
j
];

                    bestDistanceSquared 
=
 hull
[
i
].
distanceSquaredTo
(
hull
[
j
]);

                
}

            
}

        
}

    
}

    
/**

     * Returns one of the points in the farthest pair of points.

     *

     * 
@return
 one of the two points in the farthest pair of points;

     *         {
@code
 null} if no such point (because there are fewer than 2 points)

     */

    
public
 
Point2D
 either
()
 
{

        
return
 best1
;

    
}

    
/**

     * Returns the other point in the farthest pair of points.

     *

     * 
@return
 the other point in the farthest pair of points

     *         {
@code
 null} if no such point (because there are fewer than 2 points)

     */

    
public
 
Point2D
 other
()
 
{

        
return
 best2
;

    
}

    
/**

     * Returns the Eucliden distance between the farthest pair of points.

     * This quantity is also known as the diameter of the set of points.

     *

     * 
@return
 the Euclidean distance between the farthest pair of points

     *         {
@code
 Double.POSITIVE_INFINITY} if no such pair of points

     *         exist (because there are fewer than 2 points)

     */

    
public
 
double
 distance
()
 
{

        
return
 
Math
.
sqrt
(
bestDistanceSquared
);

    
}

   
/**

     * Unit tests the {
@code
 FarthestPair} data type.

     * Reads in an integer {
@code
 n} and {
@code
 n} points (specified by

     * their x– and y-coordinates) from standard input;

     * computes a farthest pair of points; and prints the pair to standard

     * output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        
Point2D
[]
 points 
=
 
new
 
Point2D
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  x  =   StdIn . readInt ();              int  y  =   StdIn . readInt ();             points [ i ]   =   new   Point2D ( x ,  y );          }          FarthestPair  farthest  =   new   FarthestPair ( points );          StdOut . println ( farthest . distance ()   +   " from "   +  farthest . either ()   +   " to "   +  farthest . other ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FenwickTree.java edu/princeton/cs/algs4/FenwickTree.java /******************************************************************************  *  Compilation:  javac FenwickTree.java  *  Execution:    java FenwickTree  *  *  A Fenwick tree.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . ArrayList ; import  java . util . Arrays ; /**  * Created by ricardodpsx @gmail .com on 4/01/15.  * 

 * In {
@code
 Fenwick Tree} structure We arrange the array in an smart way to perform efficient range queries and updates.

 * The key point is this: In a fenwick array, each position “responsible” for storing cumulative data of N previous positions (N could be 1)

 * For example:

 * array[40] stores: array[40] + array[39] … + array[32] (8 positions)

 * array[32] stores: array[32] + array[31] … + array[1]  (32 positions)

 * 

 * But, how do you know how much positions a given index is “responsible” for?

 * 

 * To know the number of items that a given array position ‘ind’ is responsible for

 * We should extract from ‘ind’ the portion up to the first significant one of the binary representation of ‘ind’

 * for example, given ind == 40 (101000 in binary), according to Fenwick algorithm

 * what We want is to extract 1000(8 in decimal).

 * 

 * This means that array[40] has cumulative information of 8 array items.

 * But We still need to know the cumulative data bellow array[40 – 8 = 32]

 * 32 is  100000 in binnary, and the portion up to the least significant one is 32 itself!

 * So array[32] has information of 32 items, and We are done!

 * 

 * So cummulative data of array[1…40] = array[40] + array[32]

 * Because 40 has information of items from 40 to 32, and 32 has information of items from 32 to  1

 * 

 * Memory usage:  O(n)

 *

 * 
@author
 Ricardo Pacheco 

 */

public
 
class
 
FenwickTree
 
{

    
int
[]
 array
;
 
// 1-indexed array, In this array We save cumulative information to perform efficient range queries and updates

    
public
 
FenwickTree
(
int
 size
)
 
{

        array 
=
 
new
 
int
[
size 
+
 
1
];

    
}

    
/**

     * Range Sum query from 1 to ind

     * ind is 1-indexed

     * 

     * Time-Complexity:    O(log(n))

     *

     * 
@param
  ind index

     * 
@return
 sum

     */

    
public
 
int
 rsq
(
int
 ind
)
 
{

        
assert
 ind 
>
 
0
;

        
int
 sum 
=
 
0
;

        
while
 
(
ind 
>
 
0
)
 
{

            sum 
+=
 array
[
ind
];

            
//Extracting the portion up to the first significant one of the binary representation of ‘ind’ and decrementing ind by that number

            ind 
-=
 ind 
&
 
(

ind
);

        
}

        
return
 sum
;

    
}

    
/**

     * Range Sum Query from a to b.

     * Search for the sum from array index from a to b

     * a and b are 1-indexed

     * 

     * Time-Complexity:    O(log(n))

     *

     * 
@param
  a left index

     * 
@param
  b right index

     * 
@return
 sum

     */

    
public
 
int
 rsq
(
int
 a
,
 
int
 b
)
 
{

        
assert
 b 
>=
 a 
&&
 a 
>
 
0
 
&&
 b 
>
 
0
;

        
return
 rsq
(
b
)
 

 rsq
(


 
1
);

    
}

    
/**

     * Update the array at ind and all the affected regions above ind.

     * ind is 1-indexed

     * 

     * Time-Complexity:    O(log(n))

     *

     * 
@param
  ind   index

     * 
@param
  value value

     */

    
public
 
void
 update
(
int
 ind
,
 
int
 value
)
 
{

        
assert
 ind 
>
 
0
;

        
while
 
(
ind 
<  array . length )   {             array [ ind ]   +=  value ;              //Extracting the portion up to the first significant one of the binary representation of 'ind' and incrementing ind by that number             ind  +=  ind  &   ( - ind );          }      }      public   int  size ()   {          return  array . length  -   1 ;      }      /**      * Read the following commands:      * init n     Initializes the array of size n all zeroes      * set a b c    Initializes the array  with [a, b, c ...]      * rsq a b      Range Sum Query for the range [a,b]      * up  i v      Update the i position of the array with value v.      * exit      * 

     * The array is 1-indexed

     * Example:

     * set 1 2 3 4 5 6

     * rsq 1 3

     * Sum from 1 to 3 = 6

     * rmq 1 3

     * Min from 1 to 3 = 1

     * input up 1 3

     * [3,2,3,4,5,6]

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
FenwickTree
 ft 
=
 
null
;

        
String
 cmd 
=
 
“cmp”
;

        
while
 
(
true
)
 
{

            
String
[]
 line 
=
 
StdIn
.
readLine
().
split
(
” ”
);

            
if
 
(
line
[
0
].
equals
(
“exit”
))
 
break
;

            
int
 arg1 
=
 
0
,
 arg2 
=
 
0
;

            
if
 
(
line
.
length 
>
 
1
)
 
{

                arg1 
=
 
Integer
.
parseInt
(
line
[
1
]);

            
}

            
if
 
(
line
.
length 
>
 
2
)
 
{

                arg2 
=
 
Integer
.
parseInt
(
line
[
2
]);

            
}

            
if
 
((
!
line
[
0
].
equals
(
“set”
)
 
&&
 
!
line
[
0
].
equals
(
“init”
))
 
&&
 ft 
==
 
null
)
 
{

                
StdOut
.
println
(
“FenwickTree not initialized”
);

                
continue
;

            
}

            
if
 
(
line
[
0
].
equals
(
“init”
))
 
{

                ft 
=
 
new
 
FenwickTree
(
arg1
);

                
for
 
(
int
 i 
=
 
1
;
 i 
<=  ft . size ();  i ++ )   {                      StdOut . print ( ft . rsq ( i ,  i )   +   " " );                  }                  StdOut . println ();              }              else   if   ( line [ 0 ]. equals ( "set" ))   {                 ft  =   new   FenwickTree ( line . length  -   1 );                  for   ( int  i  =   1 ;  i  <=  line . length  -   1 ;  i ++ )   {                     ft . update ( i ,   Integer . parseInt ( line [ i ]));                  }              }              else   if   ( line [ 0 ]. equals ( "up" ))   {                 ft . update ( arg1 ,  arg2 );                  for   ( int  i  =   1 ;  i  <=  ft . size ();  i ++ )   {                      StdOut . print ( ft . rsq ( i ,  i )   +   " " );                  }                  StdOut . println ();              }              else   if   ( line [ 0 ]. equals ( "rsq" ))   {                  StdOut . printf ( "Sum from %d to %d = %d%n" ,  arg1 ,  arg2 ,  ft . rsq ( arg1 ,  arg2 ));              }              else   {                  StdOut . println ( "Invalid command" );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FFT.java edu/princeton/cs/algs4/FFT.java /******************************************************************************  *  Compilation:  javac FFT.java  *  Execution:    java FFT n  *  Dependencies: Complex.java  *  *  Compute the FFT and inverse FFT of a length n complex sequence.  *  Bare bones implementation that runs in O(n log n) time. Our goal  *  is to optimize the clarity of the code, rather than performance.  *  *  Limitations  *  -----------  *   -  assumes n is a power of 2  *  *   -  not the most memory efficient algorithm (because it uses  *      an object type for representing complex numbers and because  *      it re-allocates memory for the subarray, instead of doing  *      in-place or reusing a single temporary array)  *    *  *  % java FFT 4  *  x  *  -------------------  *  -0.03480425839330703  *  0.07910192950176387  *  0.7233322451735928  *  0.1659819820667019  *  *  y = fft(x)  *  -------------------  *  0.9336118983487516  *  -0.7581365035668999 + 0.08688005256493803i  *  0.44344407521182005  *  -0.7581365035668999 - 0.08688005256493803i  *  *  z = ifft(y)  *  -------------------  *  -0.03480425839330703  *  0.07910192950176387 + 2.6599344570851287E-18i  *  0.7233322451735928  *  0.1659819820667019 - 2.6599344570851287E-18i  *  *  c = cconvolve(x, x)  *  -------------------  *  0.5506798633981853  *  0.23461407150576394 - 4.033186818023279E-18i  *  -0.016542951108772352  *  0.10288019294318276 + 4.033186818023279E-18i  *  *  d = convolve(x, x)  *  -------------------  *  0.001211336402308083 - 3.122502256758253E-17i  *  -0.005506167987577068 - 5.058885073636224E-17i  *  -0.044092969479563274 + 2.1934338938072244E-18i  *  0.10288019294318276 - 3.6147323062478115E-17i  *  0.5494685269958772 + 3.122502256758253E-17i  *  0.240120239493341 + 4.655566391833896E-17i  *  0.02755001837079092 - 2.1934338938072244E-18i  *  4.01805098805014E-17i  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  FFT} class provides methods for computing the   *  FFT (Fast-Fourier Transform), inverse FFT, linear convolution,  *  and circular convolution of a complex array.  *  

 *  It is a bare-bones implementation that runs in n log n time,

 *  where n is the length of the complex array. For simplicity,

 *  n must be a power of 2.

 *  Our goal is to optimize the clarity of the code, rather than performance.

 *  It is not the most memory efficient implementation because it uses

 *  objects to represents complex numbers and it it re-allocates memory

 *  for the subarray, instead of doing in-place or reusing a single temporary array.

 *  

 *  

 *  For additional documentation, see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 FFT 
{

    
private
 
static
 
final
 
Complex
 ZERO 
=
 
new
 
Complex
(
0
,
 
0
);

    
// Do not instantiate.

    
private
 FFT
()
 
{
 
}

    
/**

     * Returns the FFT of the specified complex array.

     *

     * 
@param
  x the complex array

     * 
@return
 the FFT of the complex array {
@code
 x}

     * 
@throws
 IllegalArgumentException if the length of {
@code
 x} is not a power of 2

     */

    
public
 
static
 
Complex
[]
 fft
(
Complex
[]
 x
)
 
{

        
int
 n 
=
 x
.
length
;

        
// base case

        
if
 
(

==
 
1
)
 
{

            
return
 
new
 
Complex
[]
 
{
 x
[
0
]
 
};

        
}

        
// radix 2 Cooley-Tukey FFT

        
if
 
(

%
 
2
 
!=
 
0
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“n is not a power of 2”
);

        
}

        
// fft of even terms

        
Complex
[]
 even 
=
 
new
 
Complex
[
n
/
2
];

        
for
 
(
int
 k 
=
 
0
;
 k 
<  n / 2 ;  k ++ )   {             even [ k ]   =  x [ 2 * k ];          }          Complex []  q  =  fft ( even );          // fft of odd terms          Complex []  odd   =  even ;    // reuse the array          for   ( int  k  =   0 ;  k  <  n / 2 ;  k ++ )   {             odd [ k ]   =  x [ 2 * k  +   1 ];          }          Complex []  r  =  fft ( odd );          // combine          Complex []  y  =   new   Complex [ n ];          for   ( int  k  =   0 ;  k  <  n / 2 ;  k ++ )   {              double  kth  =   - 2   *  k  *   Math . PI  /  n ;              Complex  wk  =   new   Complex ( Math . cos ( kth ),   Math . sin ( kth ));             y [ k ]         =  q [ k ]. plus ( wk . times ( r [ k ]));             y [ k  +  n / 2 ]   =  q [ k ]. minus ( wk . times ( r [ k ]));          }          return  y ;      }      /**      * Returns the inverse FFT of the specified complex array.      *      *  @param   x the complex array      *  @return  the inverse FFT of the complex array { @code  x}      *  @throws  IllegalArgumentException if the length of { @code  x} is not a power of 2      */      public   static   Complex []  ifft ( Complex []  x )   {          int  n  =  x . length ;          Complex []  y  =   new   Complex [ n ];          // take conjugate          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             y [ i ]   =  x [ i ]. conjugate ();          }          // compute forward FFT         y  =  fft ( y );          // take conjugate again          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             y [ i ]   =  y [ i ]. conjugate ();          }          // divide by n          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             y [ i ]   =  y [ i ]. scale ( 1.0   /  n );          }          return  y ;      }      /**      * Returns the circular convolution of the two specified complex arrays.      *      *  @param   x one complex array      *  @param   y the other complex array      *  @return  the circular convolution of { @code  x} and { @code  y}      *  @throws  IllegalArgumentException if the length of { @code  x} does not equal      *         the length of { @code  y} or if the length is not a power of 2      */      public   static   Complex []  cconvolve ( Complex []  x ,   Complex []  y )   {          // should probably pad x and y with 0s so that they have same length          // and are powers of 2          if   ( x . length  !=  y . length )   {              throw   new   IllegalArgumentException ( "Dimensions don't agree" );          }          int  n  =  x . length ;          // compute FFT of each sequence          Complex []  a  =  fft ( x );          Complex []  b  =  fft ( y );          // point-wise multiply          Complex []  c  =   new   Complex [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             c [ i ]   =  a [ i ]. times ( b [ i ]);          }          // compute inverse FFT          return  ifft ( c );      }      /**      * Returns the linear convolution of the two specified complex arrays.      *      *  @param   x one complex array      *  @param   y the other complex array      *  @return  the linear convolution of { @code  x} and { @code  y}      *  @throws  IllegalArgumentException if the length of { @code  x} does not equal      *         the length of { @code  y} or if the length is not a power of 2      */      public   static   Complex []  convolve ( Complex []  x ,   Complex []  y )   {          Complex []  a  =   new   Complex [ 2 * x . length ];          for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )             a [ i ]   =  x [ i ];          for   ( int  i  =  x . length ;  i  <   2 * x . length ;  i ++ )             a [ i ]   =  ZERO ;          Complex []  b  =   new   Complex [ 2 * y . length ];          for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )             b [ i ]   =  y [ i ];          for   ( int  i  =  y . length ;  i  <   2 * y . length ;  i ++ )             b [ i ]   =  ZERO ;          return  cconvolve ( a ,  b );      }      // display an array of Complex numbers to standard output      private   static   void  show ( Complex []  x ,   String  title )   {          StdOut . println ( title );          StdOut . println ( "-------------------" );          for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )   {              StdOut . println ( x [ i ]);          }          StdOut . println ();      }     /***************************************************************************     *  Test client.     ***************************************************************************/      /**      * Unit tests the { @code  FFT} class.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            int  n  =   Integer . parseInt ( args [ 0 ]);          Complex []  x  =   new   Complex [ n ];          // original data          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             x [ i ]   =   new   Complex ( i ,   0 );             x [ i ]   =   new   Complex ( StdRandom . uniform ( - 1.0 ,   1.0 ),   0 );          }         show ( x ,   "x" );          // FFT of original data          Complex []  y  =  fft ( x );         show ( y ,   "y = fft(x)" );          // take inverse FFT          Complex []  z  =  ifft ( y );         show ( z ,   "z = ifft(y)" );          // circular convolution of x with itself          Complex []  c  =  cconvolve ( x ,  x );         show ( c ,   "c = cconvolve(x, x)" );          // linear convolution of x with itself          Complex []  d  =  convolve ( x ,  x );         show ( d ,   "d = convolve(x, x)" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FibonacciMinPQ.java edu/princeton/cs/algs4/FibonacciMinPQ.java /******************************************************************************  *  Compilation: javac FibonacciMinPQ.java  *  Execution:  *  *  A Fibonacci heap.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . HashMap ; import  java . util . NoSuchElementException ; import  java . util . Comparator ; /*  *  The FibonacciMinPQ class represents a priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum operations,   *  along with the merging of two heaps together.  *  It also supports methods for peeking at the minimum key,  *  testing if the priority queue is empty, and iterating through  *  the keys.  *  It is possible to build the priority queue using a Comparator.  *  If not, the natural order relation between the keys will be used.  *    *  This implementation uses a Fibonacci heap.  *  The delete-the-minimum operation takes amortized logarithmic time.  *  The insert, min-key, is-empty, size, union and constructor take constant time.  *  *  @author Tristan Claverie  */ public   class   FibonacciMinPQ < Key >
 
implements
 
Iterable
< Key >
 
{

    
private
 
Node
 head
;
                  
//Head of the circular root list

    
private
 
Node
 min
;
                   
//Minimum Node of the root list

    
private
 
int
 size
;
                   
//Number of keys in the heap

    
private
 
final
 
Comparator
< Key >
 comp
;
 
//Comparator over the keys

    
private
 
HashMap
< Integer ,   Node >
 table 
=
 
new
 
HashMap
< Integer ,   Node >
();
 
//Used for the consolidate operation

    

    
//Represents a Node of a tree

    
private
 
class
 
Node
 
{

        
Key
 key
;
                        
//Key of this Node

        
int
 order
;
                      
//Order of the tree rooted by this Node

        
Node
 prev
,
 next
;
                
//Siblings of this Node

        
Node
 child
;
                     
//Child of this Node

    
}

    

    
/**

     * Initializes an empty priority queue

     * Worst case is O(1)

     * 
@param
 C a Comparator over the Keys

     */

    
public
 
FibonacciMinPQ
(
Comparator
< Key >
 C
)
 
{

        comp 
=
 C
;

    
}

    

    
/**

     * Initializes an empty priority queue

     * Worst case is O(1)

     */

    
public
 
FibonacciMinPQ
()
 
{

        comp 
=
 
new
 
MyComparator
();

    
}

    

    
/**

     * Initializes a priority queue with given keys

     * Worst case is O(n)

     * 
@param
 a an array of keys

     */

    
public
 
FibonacciMinPQ
(
Key
[]
 a
)
 
{

        comp 
=
 
new
 
MyComparator
();

        
for
 
(
Key
 k 
:
 a
)
 insert
(
k
);

    
}

    

    
/**

     * Initializes a priority queue with given keys

     * Worst case is O(n)

     * 
@param
 C a comparator over the keys

     * 
@param
 a an array of keys

     */

    
public
 
FibonacciMinPQ
(
Comparator
< Key >
 C
,
 
Key
[]
 a
)
 
{

        comp 
=
 C
;

        
for
 
(
Key
 k 
:
 a
)
 insert
(
k
);

    
}

    
/**

     * Whether the priority queue is empty

     * Worst case is O(1)

     * 
@return
 true if the priority queue is empty, false if not

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size 
==
 
0
;

    
}

    
/**

     * Number of elements currently on the priority queue

     * Worst case is O(1)

     * 
@return
 the number of elements on the priority queue

     */

    
public
 
int
 size
()
 
{

        
return
 size
;

    
}

    
/**

     * Insert a key in the queue

     * Worst case is O(1)

     * 
@param
 key a Key

     */

    
public
 
void
 insert
(
Key
 key
)
 
{

        
Node
 x 
=
 
new
 
Node
();

        x
.
key 
=
 key
;

        size
++
;

        head 
=
 insert
(
x
,
 head
);

        
if
 
(
min 
==
 
null
)
 min 
=
 head
;

        
else
             min 
=
 
(
greater
(
min
.
key
,
 key
))
 
?
 head 
:
 min
;

    
}

    
/**

     * Gets the minimum key currently in the queue

     * Worst case is O(1)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key currently in the priority queue

     */

    
public
 
Key
 minKey
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
return
 min
.
key
;

    
}

    
/**

     * Deletes the minimum key

     * Worst case is O(log(n)) (amortized)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key

     */

    
public
 
Key
 delMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        head 
=
 cut
(
min
,
 head
);

        
Node
 x 
=
 min
.
child
;

        
Key
 key 
=
 min
.
key
;

        min
.
key 
=
 
null
;

        
if
 
(

!=
 
null
)
 
{

            head 
=
 meld
(
head
,
 x
);

            min
.
child 
=
 
null
;

        
}

        size

;

        
if
 
(
!
isEmpty
())
 consolidate
();

        
else
            min 
=
 
null
;

        
return
 key
;

    
}

    

    
/**

     * Merges two heaps together

     * This operation is destructive

     * Worst case is O(1)

     * 
@param
 that a Fibonacci heap

     * 
@return
 the union of the two heaps

     */

    
public
 
FibonacciMinPQ
< Key >
 union
(
FibonacciMinPQ
< Key >
 that
)
 
{

        
this
.
head 
=
 meld
(
head
,
 that
.
head
);

        
this
.
min 
=
 
(
greater
(
this
.
min
.
key
,
 that
.
min
.
key
))
 
?
 that
.
min 
:
 
this
.
min
;

        
this
.
size 
=
 
this
.
size
+
that
.
size
;

        
return
 
this
;

    
}

    

    
/*************************************

     * General helper functions

     ************************************/

    

    
//Compares two keys

    
private
 
boolean
 greater
(
Key
 n
,
 
Key
 m
)
 
{

        
if
 
(

==
 
null
)
 
return
 
false
;

        
if
 
(

==
 
null
)
 
return
 
true
;

        
return
 comp
.
compare
(
n
,
m
)
 
>
 
0
;

    
}

    

    
//Assuming root1 holds a greater key than root2, root2 becomes the new root

    
private
 
void
 link
(
Node
 root1
,
 
Node
 root2
)
 
{

        root2
.
child 
=
 insert
(
root1
,
 root2
.
child
);

        root2
.
order
++
;

    
}

    

    
/*************************************

     * Function for consolidating all trees in the root list

     ************************************/

    

    
//Coalesce the roots, thus reshapes the tree

    
private
 
void
 consolidate
()
 
{

        table
.
clear
();

        
Node
 x 
=
 head
;

        
int
 maxOrder 
=
 
0
;

        min 
=
 head
;

        
Node
 y 
=
 
null
;
 
Node
 z 
=
 
null
;

        
do
 
{

            y 
=
 x
;

            x 
=
 x
.
next
;

            z 
=
 table
.
get
(
y
.
order
);

            
while
 
(

!=
 
null
)
 
{

                table
.
remove
(
y
.
order
);

                
if
 
(
greater
(
y
.
key
,
 z
.
key
))
 
{

                    link
(
y
,
 z
);

                    y 
=
 z
;

                
}
 
else
 
{

                    link
(
z
,
 y
);

                
}

                z 
=
 table
.
get
(
y
.
order
);

            
}

            table
.
put
(
y
.
order
,
 y
);

            
if
 
(
y
.
order 
>
 maxOrder
)
 maxOrder 
=
 y
.
order
;

        
}
 
while
 
(

!=
 head
);

        head 
=
 
null
;

        
for
 
(
Node
 n 
:
 table
.
values
())
 
{

            
if
 
(

!=
 
null
)
 
{

                min 
=
 greater
(
min
.
key
,
 n
.
key
)
 
?
 n 
:
 min
;

                head 
=
 insert
(
n
,
 head
);

            
}

        
}

    
}

    

    
/*************************************

     * General helper functions for manipulating circular lists

     ************************************/

    

    
//Inserts a Node in a circular list containing head, returns a new head

    
private
 
Node
 insert
(
Node
 x
,
 
Node
 head
)
 
{

        
if
 
(
head 
==
 
null
)
 
{

            x
.
prev 
=
 x
;

            x
.
next 
=
 x
;

        
}
 
else
 
{

            head
.
prev
.
next 
=
 x
;

            x
.
next 
=
 head
;

            x
.
prev 
=
 head
.
prev
;

            head
.
prev 
=
 x
;

        
}

        
return
 x
;

    
}

    

    
//Removes a tree from the list defined by the head pointer

    
private
 
Node
 cut
(
Node
 x
,
 
Node
 head
)
 
{

        
if
 
(
x
.
next 
==
 x
)
 
{

            x
.
next 
=
 
null
;

            x
.
prev 
=
 
null
;

            
return
 
null
;

        
}
 
else
 
{

            x
.
next
.
prev 
=
 x
.
prev
;

            x
.
prev
.
next 
=
 x
.
next
;

            
Node
 res 
=
 x
.
next
;

            x
.
next 
=
 
null
;

            x
.
prev 
=
 
null
;

            
if
 
(
head 
==
 x
)
  
return
 res
;

            
else
            
return
 head
;

        
}

    
}

    

    
//Merges two root lists together

    
private
 
Node
 meld
(
Node
 x
,
 
Node
 y
)
 
{

        
if
 
(

==
 
null
)
 
return
 y
;

        
if
 
(

==
 
null
)
 
return
 x
;

        x
.
prev
.
next 
=
 y
.
next
;

        y
.
next
.
prev 
=
 x
.
prev
;

        x
.
prev 
=
 y
;

        y
.
next 
=
 x
;

        
return
 x
;

    
}

    

    
/*************************************

     * Iterator

     ************************************/

    

    
/**

     * Gets an Iterator over the Keys in the priority queue in ascending order

     * The Iterator does not implement the remove() method

     * iterator() : Worst case is O(n)

     * next() :     Worst case is O(log(n)) (amortized)

     * hasNext() :  Worst case is O(1)

     * 
@return
 an Iterator over the Keys in the priority queue in ascending order

     */

    

    
public
 
Iterator
< Key >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Key >
 
{

        
private
 
FibonacciMinPQ
< Key >
 copy
;

        

        

        
//Constructor takes linear time

        
public
 
MyIterator
()
 
{

            copy 
=
 
new
 
FibonacciMinPQ
< Key >
(
comp
);

            insertAll
(
head
);

        
}

        

        
private
 
void
 insertAll
(
Node
 head
)
 
{

            
if
 
(
head 
==
 
null
)
 
return
;

            
Node
 x 
=
 head
;

            
do
 
{

                copy
.
insert
(
x
.
key
);

                insertAll
(
x
.
child
);

                x 
=
 x
.
next
;

            
}
 
while
 
(

!=
 head
);

        
}

        

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

        

        
public
 
boolean
 hasNext
()
 
{

            
return
 
!
copy
.
isEmpty
();

        
}

        

        
//Takes amortized logarithmic time

        
public
 
Key
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
return
 copy
.
delMin
();

        
}

    
}

    

    
/*************************************

     * Comparator

     ************************************/

    

    
//default Comparator

    
private
 
class
 
MyComparator
 
implements
 
Comparator
< Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

    

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/FileIndex.java
edu/princeton/cs/algs4/FileIndex.java
/******************************************************************************

 *  Compilation:  javac FileIndex.java

 *  Execution:    java FileIndex file1.txt file2.txt file3.txt …

 *  Dependencies: ST.java SET.java In.java StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/35applications/ex1.txt

 *                https://algs4.cs.princeton.edu/35applications/ex2.txt

 *                https://algs4.cs.princeton.edu/35applications/ex3.txt

 *                https://algs4.cs.princeton.edu/35applications/ex4.txt

 *

 *  % java FileIndex ex*.txt

 *  age

 *   ex3.txt

 *   ex4.txt 

 * best

 *   ex1.txt 

 * was

 *   ex1.txt

 *   ex2.txt

 *   ex3.txt

 *   ex4.txt 

 *

 *  % java FileIndex *.txt

 *

 *  % java FileIndex *.java

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
io
.
File
;

/**

 *  The {
@code
 FileIndex} class provides a client for indexing a set of files,

 *  specified as command-line arguments. It takes queries from standard input

 *  and prints each file that contains the given query.

 *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FileIndex
 
{
 

    
// Do not instantiate.

    
private
 
FileIndex
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// key = word, value = set of files containing that word

        ST
< String ,  SET < File >>
 st 
=
 
new
 ST
< String ,  SET < File >>
();

        
// create inverted index of all files

        
StdOut
.
println
(
“Indexing files”
);

        
for
 
(
String
 filename 
:
 args
)
 
{

            
StdOut
.
println
(
”  ”
 
+
 filename
);

            
File
 file 
=
 
new
 
File
(
filename
);

            
In
 in 
=
 
new
 
In
(
file
);

            
while
 
(
!
in
.
isEmpty
())
 
{

                
String
 word 
=
 in
.
readString
();

                
if
 
(
!
st
.
contains
(
word
))
 st
.
put
(
word
,
 
new
 SET
< File >
());

                SET
< File >
 set 
=
 st
.
get
(
word
);

                set
.
add
(
file
);

            
}

        
}

        
// read queries from standard input, one per line

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 query 
=
 
StdIn
.
readString
();

            
if
 
(
st
.
contains
(
query
))
 
{

                SET
< File >
 set 
=
 st
.
get
(
query
);

                
for
 
(
File
 file 
:
 set
)
 
{

                    
StdOut
.
println
(
”  ”
 
+
 file
.
getName
());

                
}

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/FlowEdge.java
edu/princeton/cs/algs4/FlowEdge.java
/******************************************************************************

 *  Compilation:  javac FlowEdge.java

 *  Execution:    java FlowEdge

 *  Dependencies: StdOut.java

 *

 *  Capacitated edge with a flow in a flow network.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 FlowEdge} class represents a capacitated edge with a 

  * flow in a {
@link
 FlowNetwork}. Each edge consists of two integers

 *  (naming the two vertices), a real-valued capacity, and a real-valued

 *  flow. The data type provides methods for accessing the two endpoints

 *  of the directed edge and the weight. It also provides methods for

 *  changing the amount of flow on the edge and determining the residual

 *  capacity of the edge.

 *  

 *  For additional documentation, see Section 6.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FlowEdge
 
{

    
// to deal with floating-point roundoff errors

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-10
;

    
private
 
final
 
int
 v
;
             
// from

    
private
 
final
 
int
 w
;
             
// to 

    
private
 
final
 
double
 capacity
;
   
// capacity

    
private
 
double
 flow
;
             
// flow

    
/**

     * Initializes an edge from vertex {
@code
 v} to vertex {
@code
 w} with

     * the given {
@code
 capacity} and zero flow.

     * 
@param
 v the tail vertex

     * 
@param
 w the head vertex

     * 
@param
 capacity the capacity of the edge

     * 
@throws
 IllegalArgumentException if either {
@code
 v} or {
@code
 w}

     *    is a negative integer

     * 
@throws
 IllegalArgumentException if {
@code
 capacity < 0.0}      */      public   FlowEdge ( int  v ,   int  w ,   double  capacity )   {          if   ( v  <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );          if   ( w  <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );          if   ( ! ( capacity  >=
 
0.0
))
 
throw
 
new
 
IllegalArgumentException
(
“Edge capacity must be non-negative”
);

        
this
.
v         
=
 v
;

        
this
.
w         
=
 w
;
  

        
this
.
capacity  
=
 capacity
;

        
this
.
flow      
=
 
0.0
;

    
}

    
/**

     * Initializes an edge from vertex {
@code
 v} to vertex {
@code
 w} with

     * the given {
@code
 capacity} and {
@code
 flow}.

     * 
@param
 v the tail vertex

     * 
@param
 w the head vertex

     * 
@param
 capacity the capacity of the edge

     * 
@param
 flow the flow on the edge

     * 
@throws
 IllegalArgumentException if either {
@code
 v} or {
@code
 w}

     *    is a negative integer

     * 
@throws
 IllegalArgumentException if {
@code
 capacity} is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 flow} is between 

     *    {
@code
 0.0} and {
@code
 capacity}.

     */

    
public
 
FlowEdge
(
int
 v
,
 
int
 w
,
 
double
 capacity
,
 
double
 flow
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );          if   ( w  <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );          if   ( ! ( capacity  >=
 
0.0
))
  
throw
 
new
 
IllegalArgumentException
(
“edge capacity must be non-negative”
);

        
if
 
(
!
(
flow 
<=  capacity ))   throw   new   IllegalArgumentException ( "flow exceeds capacity" );          if   ( ! ( flow  >=
 
0.0
))
      
throw
 
new
 
IllegalArgumentException
(
“flow must be non-negative”
);

        
this
.
v         
=
 v
;

        
this
.
w         
=
 w
;
  

        
this
.
capacity  
=
 capacity
;

        
this
.
flow      
=
 flow
;

    
}

    
/**

     * Initializes a flow edge from another flow edge.

     * 
@param
 e the edge to copy

     */

    
public
 
FlowEdge
(
FlowEdge
 e
)
 
{

        
this
.
v         
=
 e
.
v
;

        
this
.
w         
=
 e
.
w
;

        
this
.
capacity  
=
 e
.
capacity
;

        
this
.
flow      
=
 e
.
flow
;

    
}

    
/**

     * Returns the tail vertex of the edge.

     * 
@return
 the tail vertex of the edge

     */

    
public
 
int
 from
()
 
{

        
return
 v
;

    
}
  

    
/**

     * Returns the head vertex of the edge.

     * 
@return
 the head vertex of the edge

     */

    
public
 
int
 to
()
 
{

        
return
 w
;

    
}
  

    
/**

     * Returns the capacity of the edge.

     * 
@return
 the capacity of the edge

     */

    
public
 
double
 capacity
()
 
{

        
return
 capacity
;

    
}

    
/**

     * Returns the flow on the edge.

     * 
@return
 the flow on the edge

     */

    
public
 
double
 flow
()
 
{

        
return
 flow
;

    
}

    
/**

     * Returns the endpoint of the edge that is different from the given vertex

     * (unless the edge represents a self-loop in which case it returns the same vertex).

     * 
@param
 vertex one endpoint of the edge

     * 
@return
 the endpoint of the edge that is different from the given vertex

     *   (unless the edge represents a self-loop in which case it returns the same vertex)

     * 
@throws
 IllegalArgumentException if {
@code
 vertex} is not one of the endpoints

     *   of the edge

     */

    
public
 
int
 other
(
int
 vertex
)
 
{

        
if
      
(
vertex 
==
 v
)
 
return
 w
;

        
else
 
if
 
(
vertex 
==
 w
)
 
return
 v
;

        
else
 
throw
 
new
 
IllegalArgumentException
(
“invalid endpoint”
);

    
}

    
/**

     * Returns the residual capacity of the edge in the direction

     *  to the given {
@code
 vertex}.

     * 
@param
 vertex one endpoint of the edge

     * 
@return
 the residual capacity of the edge in the direction to the given vertex

     *   If {
@code
 vertex} is the tail vertex, the residual capacity equals

     *   {
@code
 capacity() – flow()}; if {
@code
 vertex} is the head vertex, the

     *   residual capacity equals {
@code
 flow()}.

     * 
@throws
 IllegalArgumentException if {
@code
 vertex} is not one of the endpoints of the edge

     */

    
public
 
double
 residualCapacityTo
(
int
 vertex
)
 
{

        
if
      
(
vertex 
==
 v
)
 
return
 flow
;
              
// backward edge

        
else
 
if
 
(
vertex 
==
 w
)
 
return
 capacity 

 flow
;
   
// forward edge

        
else
 
throw
 
new
 
IllegalArgumentException
(
“invalid endpoint”
);

    
}

    
/**

     * Increases the flow on the edge in the direction to the given vertex.

     *   If {
@code
 vertex} is the tail vertex, this increases the flow on the edge by {
@code
 delta};

     *   if {
@code
 vertex} is the head vertex, this decreases the flow on the edge by {
@code
 delta}.

     * 
@param
 vertex one endpoint of the edge

     * 
@param
 delta amount by which to increase flow

     * 
@throws
 IllegalArgumentException if {
@code
 vertex} is not one of the endpoints

     *   of the edge

     * 
@throws
 IllegalArgumentException if {
@code
 delta} makes the flow on

     *   on the edge either negative or larger than its capacity

     * 
@throws
 IllegalArgumentException if {
@code
 delta} is {
@code
 NaN}

     */

    
public
 
void
 addResidualFlowTo
(
int
 vertex
,
 
double
 delta
)
 
{

        
if
 
(
!
(
delta 
>=
 
0.0
))
 
throw
 
new
 
IllegalArgumentException
(
“Delta must be nonnegative”
);

        
if
      
(
vertex 
==
 v
)
 flow 
-=
 delta
;
           
// backward edge

        
else
 
if
 
(
vertex 
==
 w
)
 flow 
+=
 delta
;
           
// forward edge

        
else
 
throw
 
new
 
IllegalArgumentException
(
“invalid endpoint”
);

        
// round flow to 0 or capacity if within floating-point precision

        
if
 
(
Math
.
abs
(
flow
)
 
<=  FLOATING_POINT_EPSILON )             flow  =   0 ;          if   ( Math . abs ( flow  -  capacity )   <=  FLOATING_POINT_EPSILON )             flow  =  capacity ;          if   ( ! ( flow  >=
 
0.0
))
      
throw
 
new
 
IllegalArgumentException
(
“Flow is negative”
);

        
if
 
(
!
(
flow 
<=  capacity ))   throw   new   IllegalArgumentException ( "Flow exceeds capacity" );      }      /**      * Returns a string representation of the edge.      *  @return  a string representation of the edge      */      public   String  toString ()   {          return  v  +   "->”
 
+
 w 
+
 
” ”
 
+
 flow 
+
 
“/”
 
+
 capacity
;

    
}

   
/**

     * Unit tests the {
@code
 FlowEdge} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
FlowEdge
 e 
=
 
new
 
FlowEdge
(
12
,
 
23
,
 
4.56
);

        
StdOut
.
println
(
e
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/FlowNetwork.java
edu/princeton/cs/algs4/FlowNetwork.java
/******************************************************************************

 *  Compilation:  javac FlowNetwork.java

 *  Execution:    java FlowNetwork V E

 *  Dependencies: Bag.java FlowEdge.java

 *

 *  A capacitated flow network, implemented using adjacency lists.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 FlowNetwork} class represents a capacitated network

 *  with vertices named 0 through V – 1, where each directed

 *  edge is of type {
@link
 FlowEdge} and has a real-valued capacity

 *  and flow.

 *  It supports the following two primary operations: add an edge to the network,

 *  iterate over all of the edges incident to or from a vertex. It also provides

 *  methods for returning the number of vertices V and the number

 *  of edges E. Parallel edges and self-loops are permitted.

 *  

 *  This implementation uses an adjacency-lists representation, which 

 *  is a vertex-indexed array of {
@link
 Bag} objects.

 *  All operations take constant time (in the worst case) except

 *  iterating over the edges incident to a given vertex, which takes

 *  time proportional to the number of such edges.

 *  

 *  For additional documentation,

 *  see Section 6.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FlowNetwork
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;

    
private
 
int
 E
;

    
private
 
Bag
< FlowEdge >
[]
 adj
;

    

    
/**

     * Initializes an empty flow network with {
@code
 V} vertices and 0 edges.

     * 
@param
 V the number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   FlowNetwork ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Graph must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;         adj  =   ( Bag < FlowEdge >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             adj [ v ]   =   new   Bag < FlowEdge >
();

    
}

    
/**

     * Initializes a random flow network with {
@code
 V} vertices and E edges.

     * The capacities are integers between 0 and 99 and the flow values are zero.

     * 
@param
 V the number of vertices

     * 
@param
 E the number of edges

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      *  @throws  IllegalArgumentException if { @code  E < 0}      */      public   FlowNetwork ( int  V ,   int  E )   {          this ( V );          if   ( E  <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              double  capacity  =   StdRandom . uniform ( 100 );             addEdge ( new   FlowEdge ( v ,  w ,  capacity ));          }      }      /**        * Initializes a flow network from an input stream.      * The format is the number of vertices V,

     * followed by the number of edges E,

     * followed by E pairs of vertices and edge capacities,

     * with each entry separated by whitespace.

     * 
@param
 in the input stream

     * 
@throws
 IllegalArgumentException if the endpoints of any edge are not in prescribed range

     * 
@throws
 IllegalArgumentException if the number of vertices or edges is negative

     */

    
public
 
FlowNetwork
(
In
 in
)
 
{

        
this
(
in
.
readInt
());

        
int
 E 
=
 in
.
readInt
();

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of edges must be nonnegative" );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {              int  v  =  in . readInt ();              int  w  =  in . readInt ();             validateVertex ( v );             validateVertex ( w );              double  capacity  =  in . readDouble ();             addEdge ( new   FlowEdge ( v ,  w ,  capacity ));          }      }      /**      * Returns the number of vertices in the edge-weighted graph.      *  @return  the number of vertices in the edge-weighted graph      */      public   int  V ()   {          return  V ;      }      /**      * Returns the number of edges in the edge-weighted graph.      *  @return  the number of edges in the edge-weighted graph      */      public   int  E ()   {          return  E ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Adds the edge {
@code
 e} to the network.

     * 
@param
 e the edge

     * 
@throws
 IllegalArgumentException unless endpoints of edge are between

     *         {
@code
 0} and {
@code
 V-1}

     */

    
public
 
void
 addEdge
(
FlowEdge
 e
)
 
{

        
int
 v 
=
 e
.
from
();

        
int
 w 
=
 e
.
to
();

        validateVertex
(
v
);

        validateVertex
(
w
);

        adj
[
v
].
add
(
e
);

        adj
[
w
].
add
(
e
);

        E
++
;

    
}

    
/**

     * Returns the edges incident on vertex {
@code
 v} (includes both edges pointing to

     * and from {
@code
 v}).

     * 
@param
 v the vertex

     * 
@return
 the edges incident on vertex {
@code
 v} as an Iterable

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   Iterable < FlowEdge >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 adj
[
v
];

    
}

    
// return list of all edges – excludes self loops

    
public
 
Iterable
< FlowEdge >
 edges
()
 
{

        
Bag
< FlowEdge >
 list 
=
 
new
 
Bag
< FlowEdge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )              for   ( FlowEdge  e  :  adj ( v ))   {                  if   ( e . to ()   !=  v )                     list . add ( e );              }          return  list ;      }      /**      * Returns a string representation of the flow network.      * This method takes time proportional to E + V.

     * 
@return
 the number of vertices V, followed by the number of edges E,  

     *    followed by the V adjacency lists

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” ”
 
+
 E 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( v  +   ":  " );              for   ( FlowEdge  e  :  adj [ v ])   {                  if   ( e . to ()   !=  v )  s . append ( e  +   "  " );              }             s . append ( NEWLINE );          }          return  s . toString ();      }      /**      * Unit tests the { @code  FlowNetwork} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          FlowNetwork  G  =   new   FlowNetwork ( in );          StdOut . println ( G );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FloydWarshall.java edu/princeton/cs/algs4/FloydWarshall.java /******************************************************************************  *  Compilation:  javac FloydWarshall.java  *  Execution:    java FloydWarshall V E  *  Dependencies: AdjMatrixEdgeWeightedDigraph.java  *  *  Floyd-Warshall all-pairs shortest path algorithm.  *  *  % java FloydWarshall 100 500  *  *  Should check for negative cycles during triple loop; otherwise  *  intermediate numbers can get exponentially large.  *  Reference: "The Floyd-Warshall algorithm on graphs with negative cycles"  *  by Stefan Hougardy  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  FloydWarshall} class represents a data type for solving the  *  all-pairs shortest paths problem in edge-weighted digraphs with  *  no negative cycles.  *  The edge weights can be positive, negative, or zero.  *  This class finds either a shortest path between every pair of vertices  *  or a negative cycle.  *  

 *  This implementation uses the Floyd-Warshall algorithm.

 *  The constructor takes Θ(V3) time,

 *  where V is the number of vertices.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V2) extra space

 *  (not including the edge-weighted digraph).

 *  

 *  For additional documentation,    

 *  see Section 4.4 of    

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FloydWarshall
 
{

    
private
 
boolean
 hasNegativeCycle
;
  
// is there a negative cycle?

    
private
 
double
[][]
 distTo
;
         
// distTo[v][w] = length of shortest v->w path

    
private
 
DirectedEdge
[][]
 edgeTo
;
   
// edgeTo[v][w] = last edge on shortest v->w path

    
/**

     * Computes a shortest paths tree from each vertex to to every other vertex in

     * the edge-weighted digraph {
@code
 G}. If no such shortest path exists for

     * some pair of vertices, it computes a negative cycle.

     * 
@param
 G the edge-weighted digraph

     */

    
public
 
FloydWarshall
(
AdjMatrixEdgeWeightedDigraph
 G
)
 
{

        
int
 V 
=
 G
.
V
();

        distTo 
=
 
new
 
double
[
V
][
V
];

        edgeTo 
=
 
new
 
DirectedEdge
[
V
][
V
];

        
// initialize distances to infinity

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {                 distTo [ v ][ w ]   =   Double . POSITIVE_INFINITY ;              }          }          // initialize distances using edge-weighted digraph's          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( DirectedEdge  e  :  G . adj ( v ))   {                 distTo [ e . from ()][ e . to ()]   =  e . weight ();                 edgeTo [ e . from ()][ e . to ()]   =  e ;              }              // in case of self-loops              if   ( distTo [ v ][ v ]   >=
 
0.0
)
 
{

                distTo
[
v
][
v
]
 
=
 
0.0
;

                edgeTo
[
v
][
v
]
 
=
 
null
;

            
}

        
}

        
// Floyd-Warshall updates

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V ;  i ++ )   {              // compute shortest paths using only 0, 1, ..., i as intermediate vertices              for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {                  if   ( edgeTo [ v ][ i ]   ==   null )   continue ;    // optimization                  for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {                      if   ( distTo [ v ][ w ]   >
 distTo
[
v
][
i
]
 
+
 distTo
[
i
][
w
])
 
{

                        distTo
[
v
][
w
]
 
=
 distTo
[
v
][
i
]
 
+
 distTo
[
i
][
w
];

                        edgeTo
[
v
][
w
]
 
=
 edgeTo
[
i
][
w
];

                    
}

                
}

                
// check for negative cycle

                
if
 
(
distTo
[
v
][
v
]
 
<   0.0 )   {                     hasNegativeCycle  =   true ;                      return ;                  }              }          }          assert  check ( G );      }      /**      * Is there a negative cycle?      *  @return  { @code  true} if there is a negative cycle, and { @code  false} otherwise      */      public   boolean  hasNegativeCycle ()   {          return  hasNegativeCycle ;      }      /**      * Returns a negative cycle, or { @code  null} if there is no such cycle.      *  @return  a negative cycle as an iterable of edges,      * or { @code  null} if there is no such cycle      */      public   Iterable < DirectedEdge >
 negativeCycle
()
 
{

        
for
 
(
int
 v 
=
 
0
;
 v 
<  distTo . length ;  v ++ )   {              // negative cycle in v's predecessor graph              if   ( distTo [ v ][ v ]   <   0.0 )   {                  int  V  =  edgeTo . length ;                  EdgeWeightedDigraph  spt  =   new   EdgeWeightedDigraph ( V );                  for   ( int  w  =   0 ;  w  <  V ;  w ++ )                      if   ( edgeTo [ v ][ w ]   !=   null )                         spt . addEdge ( edgeTo [ v ][ w ]);                  EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( spt );                  assert  finder . hasCycle ();                  return  finder . cycle ();              }          }          return   null ;      }      /**      * Is there a path from the vertex { @code  s} to vertex { @code  t}?      *  @param   s the source vertex      *  @param   t the destination vertex      *  @return  { @code  true} if there is a path from vertex { @code  s}      *         to vertex { @code  t}, and { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= s < V}      *  @throws  IllegalArgumentException unless { @code  0 <= t < V}      */      public   boolean  hasPath ( int  s ,   int  t )   {         validateVertex ( s );         validateVertex ( t );          return  distTo [ s ][ t ]   <   Double . POSITIVE_INFINITY ;      }      /**      * Returns the length of a shortest path from vertex { @code  s} to vertex { @code  t}.      *  @param   s the source vertex      *  @param   t the destination vertex      *  @return  the length of a shortest path from vertex { @code  s} to vertex { @code  t};      *         { @code  Double.POSITIVE_INFINITY} if no such path      *  @throws  UnsupportedOperationException if there is a negative cost cycle      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   double  dist ( int  s ,   int  t )   {         validateVertex ( s );         validateVertex ( t );          if   ( hasNegativeCycle ())              throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );          return  distTo [ s ][ t ];      }      /**      * Returns a shortest path from vertex { @code  s} to vertex { @code  t}.      *  @param   s the source vertex      *  @param   t the destination vertex      *  @return  a shortest path from vertex { @code  s} to vertex { @code  t}      *         as an iterable of edges, and { @code  null} if no such path      *  @throws  UnsupportedOperationException if there is a negative cost cycle      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < DirectedEdge >
 path
(
int
 s
,
 
int
 t
)
 
{

        validateVertex
(
s
);

        validateVertex
(
t
);

        
if
 
(
hasNegativeCycle
())

            
throw
 
new
 
UnsupportedOperationException
(
“Negative cost cycle exists”
);

        
if
 
(
!
hasPath
(
s
,
 t
))
 
return
 
null
;

        
Stack
< DirectedEdge >
 path 
=
 
new
 
Stack
< DirectedEdge >
();

        
for
 
(
DirectedEdge
 e 
=
 edgeTo
[
s
][
t
];
 e 
!=
 
null
;
 e 
=
 edgeTo
[
s
][
e
.
from
()])
 
{

            path
.
push
(
e
);

        
}

        
return
 path
;

    
}

    
// check optimality conditions

    
private
 
boolean
 check
(
AdjMatrixEdgeWeightedDigraph
 G
)
 
{

        
// no negative cycle

        
if
 
(
!
hasNegativeCycle
())
 
{

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {                  for   ( DirectedEdge  e  :  G . adj ( v ))   {                      int  w  =  e . to ();                      for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {                          if   ( distTo [ i ][ w ]   >
 distTo
[
i
][
v
]
 
+
 e
.
weight
())
 
{

                            
System
.
err
.
println
(
“edge ”
 
+
 e 
+
 
” is eligible”
);

                            
return
 
false
;

                        
}

                    
}

                
}

            
}

        
}

        
return
 
true
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  distTo . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 FloydWarshall} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// random graph with V vertices and E edges, parallel edges allowed

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
AdjMatrixEdgeWeightedDigraph
 G 
=
 
new
 
AdjMatrixEdgeWeightedDigraph
(
V
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  E ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              double  weight  =   Math . round ( 100   *   ( StdRandom . uniform ()   -   0.15 ))   /   100.0 ;              if   ( v  ==  w )  G . addEdge ( new   DirectedEdge ( v ,  w ,   Math . abs ( weight )));              else  G . addEdge ( new   DirectedEdge ( v ,  w ,  weight ));          }          StdOut . println ( G );          // run Floyd-Warshall algorithm          FloydWarshall  spt  =   new   FloydWarshall ( G );          // print all-pairs shortest path distances          StdOut . printf ( "  " );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              StdOut . printf ( "%6d " ,  v );          }          StdOut . println ();          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              StdOut . printf ( "%3d: " ,  v );              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( spt . hasPath ( v ,  w ))   StdOut . printf ( "%6.2f " ,  spt . dist ( v ,  w ));                  else   StdOut . printf ( "  Inf " );              }              StdOut . println ();          }          // print negative cycle          if   ( spt . hasNegativeCycle ())   {              StdOut . println ( "Negative cost cycle:" );              for   ( DirectedEdge  e  :  spt . negativeCycle ())                  StdOut . println ( e );              StdOut . println ();          }          // print all-pairs shortest paths          else   {              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                      if   ( spt . hasPath ( v ,  w ))   {                          StdOut . printf ( "%d to %d (%5.2f)  " ,  v ,  w ,  spt . dist ( v ,  w ));                          for   ( DirectedEdge  e  :  spt . path ( v ,  w ))                              StdOut . print ( e  +   "  " );                          StdOut . println ();                      }                      else   {                          StdOut . printf ( "%d to %d no path\n" ,  v ,  w );                      }                  }              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FordFulkerson.java edu/princeton/cs/algs4/FordFulkerson.java /******************************************************************************  *  Compilation:  javac FordFulkerson.java  *  Execution:    java FordFulkerson V E  *  Dependencies: FlowNetwork.java FlowEdge.java Queue.java  *  Data files:   https://algs4.cs.princeton.edu/65maxflow/tinyFN.txt  *  *  Ford-Fulkerson algorithm for computing a max flow and   *  a min cut using shortest augmenting path rule.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  FordFulkerson} class represents a data type for computing a  *  maximum st-flow and minimum st-cut in a flow

 *  network.

 *  

 *  This implementation uses the Ford-Fulkerson algorithm with

 *  the shortest augmenting path heuristic.

 *  The constructor takes O(E V (E + V))

 *  time, where V is the number of vertices and E is

 *  the number of edges. In practice, the algorithm will run much faster.

 *  The {
@code
 inCut()} and {
@code
 value()} methods take Θ(1) time.

 *  It uses Θ(V) extra space (not including the network).

 *  

 *  If the capacities and initial flow values are all integers, then this

 *  implementation guarantees to compute an integer-valued maximum flow.

 *  If the capacities are floating-point numbers, then floating-point

 *  roundoff error can accumulate.

 *  

 *  For additional documentation, see

 *  Section 6.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FordFulkerson
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-11
;

    
private
 
final
 
int
 V
;
          
// number of vertices

    
private
 
boolean
[]
 marked
;
     
// marked[v] = true iff s->v path in residual graph

    
private
 
FlowEdge
[]
 edgeTo
;
    
// edgeTo[v] = last edge on shortest residual s->v path

    
private
 
double
 value
;
         
// current value of max flow

  

    
/**

     * Compute a maximum flow and minimum cut in the network {
@code
 G}

     * from vertex {
@code
 s} to vertex {
@code
 t}.

     *

     * 
@param
  G the flow network

     * 
@param
  s the source vertex

     * 
@param
  t the sink vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      *  @throws  IllegalArgumentException unless { @code  0 <= t < V}      *  @throws  IllegalArgumentException if { @code  s == t}      *  @throws  IllegalArgumentException if initial flow is infeasible      */      public   FordFulkerson ( FlowNetwork  G ,   int  s ,   int  t )   {         V  =  G . V ();         validate ( s );         validate ( t );          if   ( s  ==  t )                 throw   new   IllegalArgumentException ( "Source equals sink" );          if   ( ! isFeasible ( G ,  s ,  t ))   throw   new   IllegalArgumentException ( "Initial flow is infeasible" );          // while there exists an augmenting path, use it         value  =  excess ( G ,  t );          while   ( hasAugmentingPath ( G ,  s ,  t ))   {              // compute bottleneck capacity              double  bottle  =   Double . POSITIVE_INFINITY ;              for   ( int  v  =  t ;  v  !=  s ;  v  =  edgeTo [ v ]. other ( v ))   {                 bottle  =   Math . min ( bottle ,  edgeTo [ v ]. residualCapacityTo ( v ));              }              // augment flow              for   ( int  v  =  t ;  v  !=  s ;  v  =  edgeTo [ v ]. other ( v ))   {                 edgeTo [ v ]. addResidualFlowTo ( v ,  bottle );                }             value  +=  bottle ;          }          // check optimality conditions          assert  check ( G ,  s ,  t );      }      /**      * Returns the value of the maximum flow.      *      *  @return  the value of the maximum flow      */      public   double  value ()    {          return  value ;      }      /**      * Returns true if the specified vertex is on the { @code  s} side of the mincut.      *      *  @param   v vertex      *  @return  { @code  true} if vertex { @code  v} is on the { @code  s} side of the micut;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  inCut ( int  v )    {         validate ( v );          return  marked [ v ];      }      // throw an IllegalArgumentException if v is outside prescibed range      private   void  validate ( int  v )    {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
// is there an augmenting path? 

    
// if so, upon termination edgeTo[] will contain a parent-link representation of such a path

    
// this implementation finds a shortest augmenting path (fewest number of edges),

    
// which performs well both in theory and in practice

    
private
 
boolean
 hasAugmentingPath
(
FlowNetwork
 G
,
 
int
 s
,
 
int
 t
)
 
{

        edgeTo 
=
 
new
 
FlowEdge
[
G
.
V
()];

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        
// breadth-first search

        
Queue
< Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        queue
.
enqueue
(
s
);

        marked
[
s
]
 
=
 
true
;

        
while
 
(
!
queue
.
isEmpty
()
 
&&
 
!
marked
[
t
])
 
{

            
int
 v 
=
 queue
.
dequeue
();

            
for
 
(
FlowEdge
 e 
:
 G
.
adj
(
v
))
 
{

                
int
 w 
=
 e
.
other
(
v
);

                
// if residual capacity from v to w

                
if
 
(
e
.
residualCapacityTo
(
w
)
 
>
 
0
)
 
{

                    
if
 
(
!
marked
[
w
])
 
{

                        edgeTo
[
w
]
 
=
 e
;

                        marked
[
w
]
 
=
 
true
;

                        queue
.
enqueue
(
w
);

                    
}

                
}

            
}

        
}

        
// is there an augmenting path?

        
return
 marked
[
t
];

    
}

    
// return excess flow at vertex v

    
private
 
double
 excess
(
FlowNetwork
 G
,
 
int
 v
)
 
{

        
double
 excess 
=
 
0.0
;

        
for
 
(
FlowEdge
 e 
:
 G
.
adj
(
v
))
 
{

            
if
 
(

==
 e
.
from
())
 excess 
-=
 e
.
flow
();

            
else
               excess 
+=
 e
.
flow
();

        
}

        
return
 excess
;

    
}

    
// return excess flow at vertex v

    
private
 
boolean
 isFeasible
(
FlowNetwork
 G
,
 
int
 s
,
 
int
 t
)
 
{

        
// check that capacity constraints are satisfied

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              for   ( FlowEdge  e  :  G . adj ( v ))   {                  if   ( e . flow ()   <   - FLOATING_POINT_EPSILON  ||  e . flow ()   >
 e
.
capacity
()
 
+
 FLOATING_POINT_EPSILON
)
 
{

                    
System
.
err
.
println
(
“Edge does not satisfy capacity constraints: ”
 
+
 e
);

                    
return
 
false
;

                
}

            
}

        
}

        
// check that net flow into a vertex equals zero, except at source and sink

        
if
 
(
Math
.
abs
(
value 
+
 excess
(
G
,
 s
))
 
>
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
println
(
“Excess at source = ”
 
+
 excess
(
G
,
 s
));

            
System
.
err
.
println
(
“Max flow         = ”
 
+
 value
);

            
return
 
false
;

        
}

        
if
 
(
Math
.
abs
(
value 

 excess
(
G
,
 t
))
 
>
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
println
(
“Excess at sink   = ”
 
+
 excess
(
G
,
 t
));

            
System
.
err
.
println
(
“Max flow         = ”
 
+
 value
);

            
return
 
false
;

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( v  ==  s  ||  v  ==  t )   continue ;              else   if   ( Math . abs ( excess ( G ,  v ))   >
 FLOATING_POINT_EPSILON
)
 
{

                
System
.
err
.
println
(
“Net flow out of ”
 
+
 v 
+
 
” doesn’t equal zero”
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
// check optimality conditions

    
private
 
boolean
 check
(
FlowNetwork
 G
,
 
int
 s
,
 
int
 t
)
 
{

        
// check that flow is feasible

        
if
 
(
!
isFeasible
(
G
,
 s
,
 t
))
 
{

            
System
.
err
.
println
(
“Flow is infeasible”
);

            
return
 
false
;

        
}

        
// check that s is on the source side of min cut and that t is not on source side

        
if
 
(
!
inCut
(
s
))
 
{

            
System
.
err
.
println
(
“source ”
 
+
 s 
+
 
” is not on source side of min cut”
);

            
return
 
false
;

        
}

        
if
 
(
inCut
(
t
))
 
{

            
System
.
err
.
println
(
“sink ”
 
+
 t 
+
 
” is on source side of min cut”
);

            
return
 
false
;

        
}

        
// check that value of min cut = value of max flow

        
double
 mincutValue 
=
 
0.0
;

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              for   ( FlowEdge  e  :  G . adj ( v ))   {                  if   (( v  ==  e . from ())   &&  inCut ( e . from ())   &&   ! inCut ( e . to ()))                     mincutValue  +=  e . capacity ();              }          }          if   ( Math . abs ( mincutValue  -  value )   >
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
println
(
“Max flow value = ”
 
+
 value 
+
 
“, min cut value = ”
 
+
 mincutValue
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
/**

     * Unit tests the {
@code
 FordFulkerson} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// create flow network with V vertices and E edges

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 s 
=
 
0
,
 t 
=
 V

1
;

        
FlowNetwork
 G 
=
 
new
 
FlowNetwork
(
V
,
 E
);

        
StdOut
.
println
(
G
);

        
// compute maximum flow and minimum cut

        
FordFulkerson
 maxflow 
=
 
new
 
FordFulkerson
(
G
,
 s
,
 t
);

        
StdOut
.
println
(
“Max flow from ”
 
+
 s 
+
 
” to ”
 
+
 t
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              for   ( FlowEdge  e  :  G . adj ( v ))   {                  if   (( v  ==  e . from ())   &&  e . flow ()   >
 
0
)

                    
StdOut
.
println
(
”   ”
 
+
 e
);

            
}

        
}

        
// print min-cut

        
StdOut
.
print
(
“Min cut: ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( maxflow . inCut ( v ))   StdOut . print ( v  +   " " );          }          StdOut . println ();          StdOut . println ( "Max flow value = "   +   maxflow . value ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/FrequencyCounter.java edu/princeton/cs/algs4/FrequencyCounter.java /******************************************************************************  *  Compilation:  javac FrequencyCounter.java  *  Execution:    java FrequencyCounter L < input.txt  *  Dependencies: ST.java StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyTale.txt  *                https://algs4.cs.princeton.edu/31elementary/tale.txt  *                https://algs4.cs.princeton.edu/31elementary/leipzig100K.txt  *                https://algs4.cs.princeton.edu/31elementary/leipzig300K.txt  *                https://algs4.cs.princeton.edu/31elementary/leipzig1M.txt  *  *  Read in a list of words from standard input and print out  *  the most frequently occurring word that has length greater than  *  a given threshold.  *  *  % java FrequencyCounter 1 < tinyTale.txt  *  it 10  *  *  % java FrequencyCounter 8 < tale.txt  *  business 122  *  *  % java FrequencyCounter 10 < leipzig1M.txt  *  government 24763  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  FrequencyCounter} class provides a client for   *  reading in a sequence of words and printing a word (exceeding  *  a given length) that occurs most frequently. It is useful as  *  a test client for various symbol table implementations.  *  

 *  For additional documentation, see Section 3.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
FrequencyCounter
 
{

    
// Do not instantiate.

    
private
 
FrequencyCounter
()
 
{
 
}

    
/**

     * Reads in a command-line integer and sequence of words from

     * standard input and prints out a word (whose length exceeds

     * the threshold) that occurs most frequently to standard output.

     * It also prints out the number of words whose length exceeds

     * the threshold and the number of distinct such words.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 distinct 
=
 
0
,
 words 
=
 
0
;

        
int
 minlen 
=
 
Integer
.
parseInt
(
args
[
0
]);

        ST
< String ,   Integer >
 st 
=
 
new
 ST
< String ,   Integer >
();

        
// compute frequency counts

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            
if
 
(
key
.
length
()
 
<  minlen )   continue ;             words ++ ;              if   ( st . contains ( key ))   {                 st . put ( key ,  st . get ( key )   +   1 );              }              else   {                 st . put ( key ,   1 );                 distinct ++ ;              }          }          // find a key with the highest frequency count          String  max  =   "" ;         st . put ( max ,   0 );          for   ( String  word  :  st . keys ())   {              if   ( st . get ( word )   >
 st
.
get
(
max
))

                max 
=
 word
;

        
}

        
StdOut
.
println
(
max 
+
 
” ”
 
+
 st
.
get
(
max
));

        
StdOut
.
println
(
“distinct = ”
 
+
 distinct
);

        
StdOut
.
println
(
“words    = ”
 
+
 words
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/GabowSCC.java
edu/princeton/cs/algs4/GabowSCC.java
/******************************************************************************

 *  Compilation:  javac GabowSCC.java

 *  Execution:    java GabowSCC V E

 *  Dependencies: Digraph.java Stack.java TransitiveClosure.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt

 *

 *  Compute the strongly-connected components of a digraph using 

 *  Gabow’s algorithm (aka Cheriyan-Mehlhorn algorithm).

 *

 *  Runs in O(E + V) time.

 *

 *  % java GabowSCC tinyDG.txt

 *  5 components

 *  1 

 *  0 2 3 4 5

 *  9 10 11 12

 *  6 8

 *  7 

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 GabowSCC} class represents a data type for 

 *  determining the strong components in a digraph.

 *  The id operation determines in which strong component

 *  a given vertex lies; the areStronglyConnected operation

 *  determines whether two vertices are in the same strong component;

 *  and the count operation determines the number of strong

 *  components.

 *  The component identifier of a component is one of the

 *  vertices in the strong component: two vertices have the same component

 *  identifier if and only if they are in the same strong component.

 *  

 *  This implementation uses the Gabow’s algorithm.

 *  The constructor takes Θ(V + E) time,

 *  where V is the number of vertices and E is

 *  the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  For alternative implementations of the same API, see

 *  {
@link
 KosarajuSharirSCC} and {
@link
 TarjanSCC}.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
GabowSCC
 
{

    
private
 
boolean
[]
 marked
;
        
// marked[v] = has v been visited?

    
private
 
int
[]
 id
;
                
// id[v] = id of strong component containing v

    
private
 
int
[]
 preorder
;
          
// preorder[v] = preorder of v

    
private
 
int
 pre
;
                 
// preorder number counter

    
private
 
int
 count
;
               
// number of strongly-connected components

    
private
 
Stack
< Integer >
 stack1
;

    
private
 
Stack
< Integer >
 stack2
;

    
/**

     * Computes the strong components of the digraph {
@code
 G}.

     * 
@param
 G the digraph

     */

    
public
 
GabowSCC
(
Digraph
 G
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        stack1 
=
 
new
 
Stack
< Integer >
();

        stack2 
=
 
new
 
Stack
< Integer >
();

        id 
=
 
new
 
int
[
G
.
V
()];
 

        preorder 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             id [ v ]   =   - 1 ;          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              if   ( ! marked [ v ])  dfs ( G ,  v );          }          // check that id[] gives strong components          assert  check ( G );      }      private   void  dfs ( Digraph  G ,   int  v )   {           marked [ v ]   =   true ;         preorder [ v ]   =  pre ++ ;         stack1 . push ( v );         stack2 . push ( v );          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])  dfs ( G ,  w );              else   if   ( id [ w ]   ==   - 1 )   {                  while   ( preorder [ stack2 . peek ()]   >
 preorder
[
w
])

                    stack2
.
pop
();

            
}

        
}

        
// found strong component containing v

        
if
 
(
stack2
.
peek
()
 
==
 v
)
 
{

            stack2
.
pop
();

            
int
 w
;

            
do
 
{

                w 
=
 stack1
.
pop
();

                id
[
w
]
 
=
 count
;

            
}
 
while
 
(

!=
 v
);

            count
++
;

        
}

    
}

    
/**

     * Returns the number of strong components.

     * 
@return
 the number of strong components

     */

    
public
 
int
 count
()
 
{

        
return
 count
;

    
}

    
/**

     * Are vertices {
@code
 v} and {
@code
 w} in the same strong component?

     * 
@param
  v one vertex

     * 
@param
  w the other vertex

     * 
@return
 {
@code
 true} if vertices {
@code
 v} and {
@code
 w} are in the same

     *         strong component, and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      */      public   boolean  stronglyConnected ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  id [ v ]   ==  id [ w ];      }      /**      * Returns the component id of the strong component containing vertex { @code  v}.      *  @param   v the vertex      *  @return  the component id of the strong component containing vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  id ( int  v )   {         validateVertex ( v );          return  id [ v ];      }      // does the id[] array contain the strongly connected components?      private   boolean  check ( Digraph  G )   {          TransitiveClosure  tc  =   new   TransitiveClosure ( G );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))                      return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 GabowSCC} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
GabowSCC
 scc 
=
 
new
 
GabowSCC
(
G
);

        
// number of connected components

        
int
 m 
=
 scc
.
count
();

        
StdOut
.
println
(

+
 
” components”
);

        
// compute list of vertices in each strong component

        
Queue
< Integer >
[]
 components 
=
 
(
Queue
< Integer >
[])
 
new
 
Queue
[
m
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {             components [ i ]   =   new   Queue < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             components [ scc . id ( v )]. enqueue ( v );          }          // print results          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  v  :  components [ i ])   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GaussianElimination.java edu/princeton/cs/algs4/GaussianElimination.java /******************************************************************************  *  Compilation:  javac GaussianElimination.java  *  Execution:    java GaussianElimination m n  *  Dependencies: StdOut.java  *   *  Gaussian elimination with partial pivoting for m-by-n system.  *  *  % java GaussianElimination m n  *  -1.000000  *  2.000000  *  2.000000  *  *  3.000000  *  -1.000000  *  -2.000000  *   *  System is infeasible  *  *  -6.250000  *  -4.500000  *  0.000000  *  0.000000  *  1.000000  *  *  System is infeasible  *  *  -1.375000  *  1.625000  *  0.000000  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  GaussianElimination} data type provides methods  *  to solve a linear system of equations Ax = b,

 *  where A is an m-by-n matrix

 *  and b is a length n vector.

 *  

 *  This is a bare-bones implementation that uses Gaussian elimination

 *  with partial pivoting.

 *  See GaussianEliminationLite.java

 *  for a stripped-down version that assumes the matrix A is square

 *  and nonsingular. See {
@link
 GaussJordanElimination} for an alternate

 *  implementation that uses Gauss-Jordan elimination.

 *  For an industrial-strength numerical linear algebra library,

 *  see JAMA.

 *  

 *  For additional documentation, see

 *  Section 9.9

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
GaussianElimination
 
{

    
private
 
static
 
final
 
double
 EPSILON 
=
 
1e-8
;

    
private
 
final
 
int
 m
;
      
// number of rows

    
private
 
final
 
int
 n
;
      
// number of columns

    
private
 
double
[][]
 a
;
     
// m-by-(n+1) augmented matrix

    
/**

     * Solves the linear system of equations Ax = b,

     * where A is an m-by-n matrix and b

     * is a length m vector.

     *

     * 
@param
  A the m-by-n constraint matrix

     * 
@param
  b the length m right-hand-side vector

     * 
@throws
 IllegalArgumentException if the dimensions disagree, i.e.,

     *         the length of {
@code
 b} does not equal {
@code
 m}

     */

    
public
 
GaussianElimination
(
double
[][]
 A
,
 
double
[]
 b
)
 
{

        m 
=
 A
.
length
;

        n 
=
 A
[
0
].
length
;

        
if
 
(
b
.
length 
!=
 m
)
 
throw
 
new
 
IllegalArgumentException
(
“Dimensions disagree”
);

        
// build augmented matrix

        a 
=
 
new
 
double
[
m
][
n
+
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 a [ i ][ j ]   =  A [ i ][ j ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             a [ i ][ n ]   =  b [ i ];         forwardElimination ();          assert  certifySolution ( A ,  b );      }      // forward elimination      private   void  forwardElimination ()   {          for   ( int  p  =   0 ;  p  <   Math . min ( m ,  n );  p ++ )   {              // find pivot row using partial pivoting              int  max  =  p ;              for   ( int  i  =  p + 1 ;  i  <  m ;  i ++ )   {                  if   ( Math . abs ( a [ i ][ p ])   >
 
Math
.
abs
(
a
[
max
][
p
]))
 
{

                    max 
=
 i
;

                
}

            
}

            
// swap

            swap
(
p
,
 max
);

            
// singular or nearly singular

            
if
 
(
Math
.
abs
(
a
[
p
][
p
])
 
<=  EPSILON )   {                  continue ;              }              // pivot             pivot ( p );          }      }      // swap row1 and row2      private   void  swap ( int  row1 ,   int  row2 )   {          double []  temp  =  a [ row1 ];         a [ row1 ]   =  a [ row2 ];         a [ row2 ]   =  temp ;      }      // pivot on a[p][p]      private   void  pivot ( int  p )   {          for   ( int  i  =  p + 1 ;  i  <  m ;  i ++ )   {              double  alpha  =  a [ i ][ p ]   /  a [ p ][ p ];              for   ( int  j  =  p ;  j  <=  n ;  j ++ )   {                 a [ i ][ j ]   -=  alpha  *  a [ p ][ j ];              }          }      }      /**      * Returns a solution to the linear system of equations Ax = b.

     *      

     * 
@return
 a solution x to the linear system of equations

     *         Ax = b; {
@code
 null} if no such solution

     */

    
public
 
double
[]
 primal
()
 
{

        
// back substitution

        
double
[]
 x 
=
 
new
 
double
[
n
];

        
for
 
(
int
 i 
=
 
Math
.
min
(
n

1
,
 m

1
);
 i 
>=
 
0
;
 i

)
 
{

            
double
 sum 
=
 
0.0
;

            
for
 
(
int
 j 
=
 i
+
1
;
 j 
<  n ;  j ++ )   {                 sum  +=  a [ i ][ j ]   *  x [ j ];              }              if   ( Math . abs ( a [ i ][ i ])   >
 EPSILON
)

                x
[
i
]
 
=
 
(
a
[
i
][
n
]
 

 sum
)
 
/
 a
[
i
][
i
];

            
else
 
if
 
(
Math
.
abs
(
a
[
i
][
n
]
 

 sum
)
 
>
 EPSILON
)

                
return
 
null
;

        
}

        
// redundant rows

        
for
 
(
int
 i 
=
 n
;
 i 
<  m ;  i ++ )   {              double  sum  =   0.0 ;              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 sum  +=  a [ i ][ j ]   *  x [ j ];              }              if   ( Math . abs ( a [ i ][ n ]   -  sum )   >
 EPSILON
)

                
return
 
null
;

        
}

        
return
 x
;

    
}

    
/**

     * Returns true if there exists a solution to the linear system of

     * equations Ax = b.

     *      

     * 
@return
 {
@code
 true} if there exists a solution to the linear system

     *         of equations Ax = b; {
@code
 false} otherwise

     */

    
public
 
boolean
 isFeasible
()
 
{

        
return
 primal
()
 
!=
 
null
;

    
}

    
// check that Ax = b

    
private
 
boolean
 certifySolution
(
double
[][]
 A
,
 
double
[]
 b
)
 
{

        
if
 
(
!
isFeasible
())
 
return
 
true
;

        
double
[]
 x 
=
 primal
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              double  sum  =   0.0 ;              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 sum  +=  A [ i ][ j ]   *  x [ j ];              }              if   ( Math . abs ( sum  -  b [ i ])   >
 EPSILON
)
 
{

                
StdOut
.
println
(
“not feasible”
);

                
StdOut
.
println
(
“b[”
 
+
 i 
+
 
“] = ”
 
+
 b
[
i
]
 
+
 
“, sum = ”
 
+
 sum
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
/**

     * Unit tests the {
@code
 GaussianElimination} data type.

     */

    
private
 
static
 
void
 test
(
String
 name
,
 
double
[][]
 A
,
 
double
[]
 b
)
 
{

        
StdOut
.
println
(
“—————————————————-”
);

        
StdOut
.
println
(
name
);

        
StdOut
.
println
(
“—————————————————-”
);

        
GaussianElimination
 gaussian 
=
 
new
 
GaussianElimination
(
A
,
 b
);

        
double
[]
 x 
=
 gaussian
.
primal
();

        
if
 
(
gaussian
.
isFeasible
())
 
{

            
for
 
(
int
 i 
=
 
0
;
 i 
<  x . length ;  i ++ )   {                  StdOut . printf ( "%.6f\n" ,  x [ i ]);              }          }          else   {              StdOut . println ( "System is infeasible" );          }          StdOut . println ();          StdOut . println ();      }      // 3-by-3 nonsingular system      private   static   void  test1 ()   {          double [][]  A  =   {              {   0 ,   1 ,    1   },              {   2 ,   4 ,   - 2   },              {   0 ,   3 ,   15   }          };          double []  b  =   {   4 ,   2 ,   36   };         test ( "test 1 (3-by-3 system, nonsingular)" ,  A ,  b );      }      // 3-by-3 nonsingular system      private   static   void  test2 ()   {          double [][]  A  =   {              {    1 ,   - 3 ,     1   },              {    2 ,   - 8 ,     8   },              {   - 6 ,    3 ,   - 15   }          };          double []  b  =   {   4 ,   - 2 ,   9   };         test ( "test 2 (3-by-3 system, nonsingular)" ,  A ,  b );      }      // 5-by-5 singular: no solutions      private   static   void  test3 ()   {          double [][]  A  =   {              {    2 ,   - 3 ,   - 1 ,    2 ,    3   },              {    4 ,   - 4 ,   - 1 ,    4 ,   11   },              {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },              {    0 ,    2 ,    1 ,    0 ,    4   },              {   - 4 ,    6 ,    0 ,    0 ,    7   },          };          double []  b  =   {   4 ,   4 ,   9 ,   - 6 ,   5   };         test ( "test 3 (5-by-5 system, no solutions)" ,  A ,  b );      }      // 5-by-5 singular: infinitely many solutions      private   static   void  test4 ()   {          double [][]  A  =   {              {    2 ,   - 3 ,   - 1 ,    2 ,    3   },              {    4 ,   - 4 ,   - 1 ,    4 ,   11   },              {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },              {    0 ,    2 ,    1 ,    0 ,    4   },              {   - 4 ,    6 ,    0 ,    0 ,    7   },          };          double []  b  =   {   4 ,   4 ,   9 ,   - 5 ,   5   };         test ( "test 4 (5-by-5 system, infinitely many solutions)" ,  A ,  b );      }      // 3-by-3 singular: no solutions      private   static   void  test5 ()   {          double [][]  A  =   {              {    2 ,   - 1 ,    1   },              {    3 ,    2 ,   - 4   },              {   - 6 ,    3 ,   - 3   },          };          double []  b  =   {   1 ,   4 ,   2   };         test ( "test 5 (3-by-3 system, no solutions)" ,  A ,  b );      }      // 3-by-3 singular: infinitely many solutions      private   static   void  test6 ()   {          double [][]  A  =   {              {    1 ,   - 1 ,    2   },              {    4 ,    4 ,   - 2   },              {   - 2 ,    2 ,   - 4   },          };          double []  b  =   {   - 3 ,   1 ,   6   };         test ( "test 6 (3-by-3 system, infinitely many solutions)" ,  A ,  b );      }      // 4-by-3 full rank and feasible system      private   static   void  test7 ()   {          double [][]  A  =   {              {   0 ,   1 ,    1   },              {   2 ,   4 ,   - 2   },              {   0 ,   3 ,   15   },              {   2 ,   8 ,   14   }          };          double []  b  =   {   4 ,   2 ,   36 ,   42   };         test ( "test 7 (4-by-3 system, full rank)" ,  A ,  b );      }      // 4-by-3 full rank and infeasible system      private   static   void  test8 ()   {          double [][]  A  =   {              {   0 ,   1 ,    1   },              {   2 ,   4 ,   - 2   },              {   0 ,   3 ,   15   },              {   2 ,   8 ,   14   }          };          double []  b  =   {   4 ,   2 ,   36 ,   40   };         test ( "test 8 (4-by-3 system, no solution)" ,  A ,  b );      }      // 3-by-4 full rank system      private   static   void  test9 ()   {          double [][]  A  =   {              {    1 ,   - 3 ,     1 ,    1   },              {    2 ,   - 8 ,     8 ,    2   },              {   - 6 ,    3 ,   - 15 ,    3   }          };          double []  b  =   {   4 ,   - 2 ,   9   };         test ( "test 9 (3-by-4 system, full rank)" ,  A ,  b );      }      /**      * Unit tests the { @code  GaussianElimination} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {         test1 ();         test2 ();         test3 ();         test4 ();         test5 ();         test6 ();         test7 ();         test8 ();         test9 ();          // n-by-n random system          int  n  =   Integer . parseInt ( args [ 0 ]);          double [][]  A  =   new   double [ n ][ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 A [ i ][ j ]   =   StdRandom . uniform ( 1000 );          double []  b  =   new   double [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             b [ i ]   =   StdRandom . uniform ( 1000 );         test ( n  +   "-by-"   +  n  +   " (probably nonsingular)" ,  A ,  b );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GaussJordanElimination.java edu/princeton/cs/algs4/GaussJordanElimination.java /******************************************************************************  *  Compilation:  javac GaussJordanElimination.java  *  Execution:    java GaussJordanElimination n  *  Dependencies: StdOut.java  *   *  Finds a solutions to Ax = b using Gauss-Jordan elimination with partial  *  pivoting. If no solution exists, find a solution to yA = 0, yb != 0,  *  which serves as a certificate of infeasibility.  *  *  % java GaussJordanElimination  *  -1.000000  *  2.000000  *  2.000000  *  *  3.000000  *  -1.000000  *  -2.000000  *   *  System is infeasible  *  *  -6.250000  *  -4.500000  *  0.000000  *  0.000000  *  1.000000  *  *  System is infeasible  *  *  -1.375000  *  1.625000  *  0.000000  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  GaussJordanElimination} data type provides methods  *  to solve a linear system of equations Ax = b,

 *  where A is an n-by-n matrix

 *  and b is a length n vector.

 *  If no solution exists, it finds a solution y to

 *  yA = 0, yb ≠ 0, which

 *  which serves as a certificate of infeasibility.

 *  

 *  This implementation uses Gauss-Jordan elimination with partial pivoting.

 *  See {
@link
 GaussianElimination} for an implementation that uses

 *  Gaussian elimination (but does not provide the certificate of infeasibility).

 *  For an industrial-strength numerical linear algebra library,

 *  see JAMA. 

 *  

 *  For additional documentation, see

 *  Section 9.9

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
GaussJordanElimination
 
{

    
private
 
static
 
final
 
double
 EPSILON 
=
 
1e-8
;

    
private
 
final
 
int
 n
;
      
// n-by-n system

    
private
 
double
[][]
 a
;
     
// n-by-(n+1) augmented matrix

    
// Gauss-Jordan elimination with partial pivoting

    
/**

     * Solves the linear system of equations Ax = b,

     * where A is an n-by-n matrix and b

     * is a length n vector.

     *

     * 
@param
  A the n-by-n constraint matrix

     * 
@param
  b the length n right-hand-side vector

     */

    
public
 
GaussJordanElimination
(
double
[][]
 A
,
 
double
[]
 b
)
 
{

        n 
=
 b
.
length
;

        
// build augmented matrix

        a 
=
 
new
 
double
[
n
][
n
+
n
+
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 a [ i ][ j ]   =  A [ i ][ j ];          // only needed if you want to find certificate of infeasibility (or compute inverse)          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             a [ i ][ n + i ]   =   1.0 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             a [ i ][ n + n ]   =  b [ i ];         solve ();          assert  certifySolution ( A ,  b );      }      private   void  solve ()   {          // Gauss-Jordan elimination          for   ( int  p  =   0 ;  p  <  n ;  p ++ )   {              // show();              // find pivot row using partial pivoting              int  max  =  p ;              for   ( int  i  =  p + 1 ;  i  <  n ;  i ++ )   {                  if   ( Math . abs ( a [ i ][ p ])   >
 
Math
.
abs
(
a
[
max
][
p
]))
 
{

                    max 
=
 i
;

                
}

            
}

            
// exchange row p with row max

            swap
(
p
,
 max
);

            
// singular or nearly singular

            
if
 
(
Math
.
abs
(
a
[
p
][
p
])
 
<=  EPSILON )   {                  continue ;                  // throw new ArithmeticException("Matrix is singular or nearly singular");              }              // pivot             pivot ( p ,  p );          }          // show();      }      // swap row1 and row2      private   void  swap ( int  row1 ,   int  row2 )   {          double []  temp  =  a [ row1 ];         a [ row1 ]   =  a [ row2 ];         a [ row2 ]   =  temp ;      }      // pivot on entry (p, q) using Gauss-Jordan elimination      private   void  pivot ( int  p ,   int  q )   {          // everything but row p and column q          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              double  alpha  =  a [ i ][ q ]   /  a [ p ][ q ];              for   ( int  j  =   0 ;  j  <=  n + n ;  j ++ )   {                  if   ( i  !=  p  &&  j  !=  q )  a [ i ][ j ]   -=  alpha  *  a [ p ][ j ];              }          }          // zero out column q          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              if   ( i  !=  p )  a [ i ][ q ]   =   0.0 ;          // scale row p (ok to go from q+1 to n, but do this for consistency with simplex pivot)          for   ( int  j  =   0 ;  j  <=  n + n ;  j ++ )              if   ( j  !=  q )  a [ p ][ j ]   /=  a [ p ][ q ];         a [ p ][ q ]   =   1.0 ;      }      /**      * Returns a solution to the linear system of equations Ax = b.

     *      

     * 
@return
 a solution x to the linear system of equations

     *         Ax = b; {
@code
 null} if no such solution

     */

    
public
 
double
[]
 primal
()
 
{

        
double
[]
 x 
=
 
new
 
double
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   ( Math . abs ( a [ i ][ i ])   >
 EPSILON
)

                x
[
i
]
 
=
 a
[
i
][
n
+
n
]
 
/
 a
[
i
][
i
];

            
else
 
if
 
(
Math
.
abs
(
a
[
i
][
n
+
n
])
 
>
 EPSILON
)

                
return
 
null
;

        
}

        
return
 x
;

    
}

    
/**

     * Returns a solution to the linear system of equations yA = 0,

     * yb ≠ 0.

     *      

     * 
@return
 a solution y to the linear system of equations

     *         yA = 0, yb ≠ 0; {
@code
 null} if no such solution

     */

    
public
 
double
[]
 dual
()
 
{

        
double
[]
 y 
=
 
new
 
double
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   (( Math . abs ( a [ i ][ i ])   <=  EPSILON )   &&   ( Math . abs ( a [ i ][ n + n ])   >
 EPSILON
))
 
{

                
for
 
(
int
 j 
=
 
0
;
 j 
<  n ;  j ++ )                     y [ j ]   =  a [ i ][ n + j ];                  return  y ;              }          }          return   null ;      }      /**      * Returns true if there exists a solution to the linear system of      * equations Ax = b.

     *      

     * 
@return
 {
@code
 true} if there exists a solution to the linear system

     *         of equations Ax = b; {
@code
 false} otherwise

     */

    
public
 
boolean
 isFeasible
()
 
{

        
return
 primal
()
 
!=
 
null
;

    
}

    
// print the tableaux

    
private
 
void
 show
()
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  StdOut . printf ( "%8.3f " ,  a [ i ][ j ]);              }              StdOut . printf ( "| " );              for   ( int  j  =  n ;  j  <  n + n ;  j ++ )   {                  StdOut . printf ( "%8.3f " ,  a [ i ][ j ]);              }              StdOut . printf ( "| %8.3f\n" ,  a [ i ][ n + n ]);          }          StdOut . println ();      }      // check that Ax = b or yA = 0, yb != 0      private   boolean  certifySolution ( double [][]  A ,   double []  b )   {          // check that Ax = b          if   ( isFeasible ())   {              double []  x  =  primal ();              for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                  double  sum  =   0.0 ;                  for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                     sum  +=  A [ i ][ j ]   *  x [ j ];                  }                  if   ( Math . abs ( sum  -  b [ i ])   >
 EPSILON
)
 
{

                    
StdOut
.
println
(
“not feasible”
);

                    
StdOut
.
printf
(
“b[%d] = %8.3f, sum = %8.3f\n”
,
 i
,
 b
[
i
],
 sum
);

                    
return
 
false
;

                
}

            
}

            
return
 
true
;

        
}

        
// or that yA = 0, yb != 0

        
else
 
{

            
double
[]
 y 
=
 dual
();

            
for
 
(
int
 j 
=
 
0
;
 j 
<  n ;  j ++ )   {                  double  sum  =   0.0 ;                  for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                     sum  +=  A [ i ][ j ]   *  y [ i ];                  }                  if   ( Math . abs ( sum )   >
 EPSILON
)
 
{

                    
StdOut
.
println
(
“invalid certificate of infeasibility”
);

                    
StdOut
.
printf
(
“sum = %8.3f\n”
,
 sum
);

                    
return
 
false
;

                
}

            
}

            
double
 sum 
=
 
0.0
;

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {                 sum  +=  y [ i ]   *  b [ i ];              }              if   ( Math . abs ( sum )   <  EPSILON )   {                  StdOut . println ( "invalid certificate of infeasibility" );                  StdOut . printf ( "yb  = %8.3f\n" ,  sum );                  return   false ;              }              return   true ;          }      }      private   static   void  test ( String  name ,   double [][]  A ,   double []  b )   {          StdOut . println ( "----------------------------------------------------" );          StdOut . println ( name );          StdOut . println ( "----------------------------------------------------" );          GaussJordanElimination  gaussian  =   new   GaussJordanElimination ( A ,  b );          if   ( gaussian . isFeasible ())   {              StdOut . println ( "Solution to Ax = b" );              double []  x  =  gaussian . primal ();              for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )   {                  StdOut . printf ( "%10.6f\n" ,  x [ i ]);              }          }          else   {              StdOut . println ( "Certificate of infeasibility" );              double []  y  =  gaussian . dual ();              for   ( int  j  =   0 ;  j  <  y . length ;  j ++ )   {                  StdOut . printf ( "%10.6f\n" ,  y [ j ]);              }          }          StdOut . println ();          StdOut . println ();      }      // 3-by-3 nonsingular system      private   static   void  test1 ()   {          double [][]  A  =   {              {   0 ,   1 ,    1   },              {   2 ,   4 ,   - 2   },              {   0 ,   3 ,   15   }          };          double []  b  =   {   4 ,   2 ,   36   };         test ( "test 1" ,  A ,  b );      }      // 3-by-3 nonsingular system      private   static   void  test2 ()   {          double [][]  A  =   {              {    1 ,   - 3 ,     1   },              {    2 ,   - 8 ,     8   },              {   - 6 ,    3 ,   - 15   }          };          double []  b  =   {   4 ,   - 2 ,   9   };         test ( "test 2" ,  A ,  b );      }      // 5-by-5 singular: no solutions      // y = [ -1, 0, 1, 1, 0 ]      private   static   void  test3 ()   {          double [][]  A  =   {              {    2 ,   - 3 ,   - 1 ,    2 ,    3   },              {    4 ,   - 4 ,   - 1 ,    4 ,   11   },              {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },              {    0 ,    2 ,    1 ,    0 ,    4   },              {   - 4 ,    6 ,    0 ,    0 ,    7   },          };          double []  b  =   {   4 ,   4 ,   9 ,   - 6 ,   5   };         test ( "test 3" ,  A ,  b );      }      // 5-by-5 singluar: infinitely many solutions      private   static   void  test4 ()   {          double [][]  A  =   {              {    2 ,   - 3 ,   - 1 ,    2 ,    3   },              {    4 ,   - 4 ,   - 1 ,    4 ,   11   },              {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },              {    0 ,    2 ,    1 ,    0 ,    4   },              {   - 4 ,    6 ,    0 ,    0 ,    7   },          };          double []  b  =   {   4 ,   4 ,   9 ,   - 5 ,   5   };         test ( "test 4" ,  A ,  b );      }      // 3-by-3 singular: no solutions      // y = [ 1, 0, 1/3 ]      private   static   void  test5 ()   {          double [][]  A  =   {              {    2 ,   - 1 ,    1   },              {    3 ,    2 ,   - 4   },              {   - 6 ,    3 ,   - 3   },          };          double []  b  =   {   1 ,   4 ,   2   };         test ( "test 5" ,  A ,  b );      }      // 3-by-3 singular: infinitely many solutions      private   static   void  test6 ()   {          double [][]  A  =   {              {    1 ,   - 1 ,    2   },              {    4 ,    4 ,   - 2   },              {   - 2 ,    2 ,   - 4   },          };          double []  b  =   {   - 3 ,   1 ,   6   };         test ( "test 6 (infinitely many solutions)" ,  A ,  b );      }      /**      * Unit tests the { @code  GaussJordanElimination} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {         test1 ();         test2 ();         test3 ();         test4 ();         test5 ();         test6 ();          // n-by-n random system (likely full rank)          int  n  =   Integer . parseInt ( args [ 0 ]);          double [][]  A  =   new   double [ n ][ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 A [ i ][ j ]   =   StdRandom . uniform ( 1000 );          double []  b  =   new   double [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             b [ i ]   =   StdRandom . uniform ( 1000 );         test ( "random "   +  n  +   "-by-"   +  n  +   " (likely full rank)" ,  A ,  b );          // n-by-n random system (likely infeasible)         A  =   new   double [ n ][ n ];          for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 A [ i ][ j ]   =   StdRandom . uniform ( 1000 );          for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )   {              double  alpha  =   StdRandom . uniform ( 11 )   -   5.0 ;              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 A [ n - 1 ][ j ]   +=  alpha  *  A [ i ][ j ];              }          }         b  =   new   double [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             b [ i ]   =   StdRandom . uniform ( 1000 );         test ( "random "   +  n  +   "-by-"   +  n  +   " (likely infeasible)" ,  A ,  b );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Genome.java edu/princeton/cs/algs4/Genome.java /******************************************************************************  *  Compilation:  javac Genome.java  *  Execution:    java Genome - < input.txt   (compress)  *  Execution:    java Genome + < input.txt   (expand)  *  Dependencies: BinaryIn.java BinaryOut.java  *  Data files:   https://algs4.cs.princeton.edu/55compression/genomeTiny.txt  *  *  Compress or expand a genomic sequence using a 2-bit code.  *  *  % more genomeTiny.txt  *  ATAGATGCATAGCGCATAGCTAGATGTGCTAGC  *  *  % java Genome - < genomeTiny.txt | java Genome +  *  ATAGATGCATAGCGCATAGCTAGATGTGCTAGC  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Genome} class provides static methods for compressing  *  and expanding a genomic sequence using a 2-bit code.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Genome
 
{

    
// Do not instantiate.

    
private
 
Genome
()
 
{
 
}

    
/**

     * Reads a sequence of 8-bit extended ASCII characters over the alphabet

     * { A, C, T, G } from standard input; compresses them using two bits per

     * character; and writes the results to standard output.

     */

    
public
 
static
 
void
 compress
()
 
{
 

        
Alphabet
 DNA 
=
 
Alphabet
.
DNA
;

        
String
 s 
=
 
BinaryStdIn
.
readString
();

        
int
 n 
=
 s
.
length
();

        
BinaryStdOut
.
write
(
n
);

        
// Write two-bit code for char. 

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  d  =  DNA . toIndex ( s . charAt ( i ));              BinaryStdOut . write ( d ,   2 );          }          BinaryStdOut . close ();      }        /**      * Reads a binary sequence from standard input; converts each two bits      * to an 8-bit extended ASCII character over the alphabet { A, C, T, G };      * and writes the results to standard output.      */      public   static   void  expand ()   {          Alphabet  DNA  =   Alphabet . DNA ;          int  n  =   BinaryStdIn . readInt ();          // Read two bits; write char.           for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              char  c  =   BinaryStdIn . readChar ( 2 );              BinaryStdOut . write ( DNA . toChar ( c ),   8 );          }          BinaryStdOut . close ();      }      /**      * Sample client that calls { @code  compress()} if the command-line      * argument is "-" an { @code  expand()} if it is "+".      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          if        ( args [ 0 ]. equals ( "-" ))  compress ();          else   if   ( args [ 0 ]. equals ( "+" ))  expand ();          else   throw   new   IllegalArgumentException ( "Illegal command line argument" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GlobalMincut.java edu/princeton/cs/algs4/GlobalMincut.java /******************************************************************************  *  Compilation:  javac GlobalMincut.java  *  Execution:    java  GlobalMincut filename.txt  *  Dependencies: EdgeWeightedGraph.java Edge.java UF.java   *                IndexMaxPQ.java FlowNetwork.java FlowEdge.java   *                FordFulkerson.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt  *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt  *  *  Computes a minimum cut using Stoer-Wagner's algorithm.  *  *  % java GlobalMincut tinyEWG.txt   *    Min cut: 5   *    Min cut weight = 0.9500000000000001  *      *  % java GlobalMincut mediumEWG.txt   *    Min cut: 25 60 63 96 199 237   *    Min cut weight = 0.14021  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  GlobalMincut} class represents a data type for computing a  *  global minimum cut in a graph with non-negative edge weights.

 *  A cut is a partition of the vertices into two nonempty subsets.

 *  An edge that has one

 *  endpoint in each subset of a cut is a crossing edge. The weight

 *  of a cut is the sum of the weights of its crossing edges.

 *  A global minimum cut whose weight is no larger than the weight

 *  of any other cut.

 *  

 *  This is an implementation of Stoer-Wagner’s algorithm.

 *  The constructor takes

 *  O(V (V + E) log V) time,

 *  where V is the number of vertices and E is the

 *  number of edges. 

 *  The weight and isCut methods take Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph).

 *  

 *  For additional documentation, see

 *  

     *  

  • M. Stoer and F. Wagner (1997). A simple min-cut algorithm. Journal of

     *  the ACM , 44(4):585-591.

     *  

 * 

 * 
@author
 Marcelo Silva

 */

public
 
class
 
GlobalMincut
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-11
;

    
// the weight of the minimum cut

    
private
 
double
 weight 
=
 
Double
.
POSITIVE_INFINITY
;

    
// cut[v] = true if v is on the first subset of vertices of the minimum cut;

    
// or false if v is on the second subset

    
private
 
boolean
[]
 cut
;

    
// number of vertices

    
private
 
int
 V
;

    
/**

     * This helper class represents the cut-of-the-phase. The

     * cut-of-the-phase is a minimum s-t-cut in the current graph,

     * where {
@code
 s} and {
@code
 t} are the two vertices added last in the

     * phase.

     */

    
private
 
class
 
CutPhase
 
{

        
private
 
double
 weight
;
 
// the weight of the minimum s-t cut

        
private
 
int
 s
;
         
// the vertex s

        
private
 
int
 t
;
         
// the vertex t

        
public
 
CutPhase
(
double
 weight
,
 
int
 s
,
 
int
 t
)
 
{

            
this
.
weight 
=
 weight
;

            
this
.

=
 s
;

            
this
.

=
 t
;

        
}

    
}

    
/**

     * Computes a minimum cut in an edge-weighted graph.

     * 

     * 
@param
 G the edge-weighted graph

     * 
@throws
 IllegalArgumentException if the number of vertices of {
@code
 G}

     *             is less than {
@code
 2}.

     * 
@throws
 IllegalArgumentException if any edge weight is negative

     */

    
public
 
GlobalMincut
(
EdgeWeightedGraph
 G
)
 
{

        V 
=
 G
.
V
();

        validate
(
G
);

        minCut
(
G
,
 
0
);

        
assert
 check
(
G
);

    
}

    
/**

     * Validates the edge-weighted graph.

     * 

     * 
@param
 G the edge-weighted graph

     * 
@throws
 IllegalArgumentException if the number of vertices of {
@code
 G}

     *             is less than {
@code
 2} or if any edge weight is negative

     */

    
private
 
void
 validate
(
EdgeWeightedGraph
 G
)
 
{

        
if
 
(
G
.
V
()
 
<   2 )   throw   new   IllegalArgumentException ( "number of vertices of G is less than 2" );          for   ( Edge  e  :  G . edges ())   {              if   ( e . weight ()   <   0 )   throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );          }      }      /**      * Returns the weight of the minimum cut.      *       *  @return  the weight of the minimum cut      */      public   double  weight ()   {          return  weight ;      }      /**      * Returns { @code  true} if the vertex { @code  v} is one side of the      * mincut and { @code  false} otherwise. An edge vw

     * crosses the mincut if and only if v and w have

     * opposite parity.

     * 

     * 
@param
 v the vertex to check

     * 
@return
 {
@code
 true} if the vertex {
@code
 v} is on the first subset of

     *         vertices of the minimum cut; or {
@code
 false} if the vertex

     *         {
@code
 v} is on the second subset.

     * 
@throws
 IllegalArgumentException unless vertex {
@code
 v} is between

     *             {
@code
 0 <= v < V}      */      public   boolean  cut ( int  v )   {         validateVertex ( v );          return  cut [ v ];      }      /**      * Makes a cut for the current edge-weighted graph by partitioning its      * vertices into two nonempty subsets. The vertices connected to the      * vertex { @code  t} belong to the first subset. Other vertices not connected      * to { @code  t} belong to the second subset.      *       *  @param  t the vertex { @code  t}      *  @param  uf the union-find data type      */      private   void  makeCut ( int  t ,  UF uf )   {          for   ( int  v  =   0 ;  v  <  cut . length ;  v ++ )   {             cut [ v ]   =   ( uf . find ( v )   ==  uf . find ( t ));          }      }      /**      * Computes a minimum cut of the edge-weighted graph. Precisely, it computes      * the lightest of the cuts-of-the-phase which yields the desired minimum      * cut.      *       *  @param  G the edge-weighted graph      *  @param  a the starting vertex      */      private   void  minCut ( EdgeWeightedGraph  G ,   int  a )   {         UF uf  =   new  UF ( G . V ());          boolean []  marked  =   new   boolean [ G . V ()];         cut  =   new   boolean [ G . V ()];          CutPhase  cp  =   new   CutPhase ( 0.0 ,  a ,  a );          for   ( int  v  =  G . V ();  v  >
 
1
;
 v

)
 
{

            cp 
=
 minCutPhase
(
G
,
 marked
,
 cp
);

            
if
 
(
cp
.
weight 
<  weight )   {                 weight  =  cp . weight ;                 makeCut ( cp . t ,  uf );              }             G  =  contractEdge ( G ,  cp . s ,  cp . t );             marked [ cp . t ]   =   true ;             uf . union ( cp . s ,  cp . t );          }      }      /**      * Returns the cut-of-the-phase. The cut-of-the-phase is a minimum s-t-cut      * in the current graph, where { @code  s} and { @code  t} are the two vertices      * added last in the phase. This algorithm is known in the literature as      * maximum adjacency search or maximum cardinality search.

     * 

     * 
@param
 G the edge-weighted graph

     * 
@param
 marked the array of contracted vertices, where {
@code
 marked[v]}

     *            is {
@code
 true} if the vertex {
@code
 v} was already

     *            contracted; or {
@code
 false} otherwise

     * 
@param
 cp the previous cut-of-the-phase

     * 
@return
 the cut-of-the-phase

     */

    
private
 
CutPhase
 minCutPhase
(
EdgeWeightedGraph
 G
,
 
boolean
[]
 marked
,
 
CutPhase
 cp
)
 
{

        
IndexMaxPQ
< Double >
 pq 
=
 
new
 
IndexMaxPQ
< Double >
(
G
.
V
());

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( v  !=  cp . s  &&   ! marked [ v ])  pq . insert ( v ,   0.0 );          }         pq . insert ( cp . s ,   Double . POSITIVE_INFINITY );          while   ( ! pq . isEmpty ())   {              int  v  =  pq . delMax ();             cp . s  =  cp . t ;             cp . t  =  v ;              for   ( Edge  e  :  G . adj ( v ))   {                  int  w  =  e . other ( v );                  if   ( pq . contains ( w ))  pq . increaseKey ( w ,  pq . keyOf ( w )   +  e . weight ());              }          }         cp . weight  =   0.0 ;          for   ( Edge  e  :  G . adj ( cp . t ))   {             cp . weight  +=  e . weight ();          }          return  cp ;      }      /**      * Contracts the edges incidents on the vertices { @code  s} and { @code  t} of      * the given edge-weighted graph.      *       *  @param  G the edge-weighted graph      *  @param  s the vertex { @code  s}      *  @param  t the vertex { @code  t}      *  @return  a new edge-weighted graph for which the edges incidents on the      *         vertices { @code  s} and { @code  t} were contracted      */      private   EdgeWeightedGraph  contractEdge ( EdgeWeightedGraph  G ,   int  s ,   int  t )   {          EdgeWeightedGraph  H  =   new   EdgeWeightedGraph ( G . V ());          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( Edge  e  :  G . adj ( v ))   {                  int  w  =  e . other ( v );                  if   ( v  ==  s  &&  w  ==  t  ||  v  ==  t  &&  w  ==  s )   continue ;                  if   ( v  <  w )   {                      if   ( w  ==  t )       H . addEdge ( new   Edge ( v ,  s ,  e . weight ()));                      else   if   ( v  ==  t )  H . addEdge ( new   Edge ( w ,  s ,  e . weight ()));                      else              H . addEdge ( new   Edge ( v ,  w ,  e . weight ()));                  }              }          }          return  H ;      }      /**      * Checks optimality conditions.      *       *  @param  G the edge-weighted graph      *  @return  { @code  true} if optimality conditions are fine      */      private   boolean  check ( EdgeWeightedGraph  G )   {          // compute min st-cut for all pairs s and t          // shortcut: s must appear on one side of global mincut,          // so it suffices to try all pairs s-v for some fixed s          double  value  =   Double . POSITIVE_INFINITY ;          for   ( int  s  =   0 ,  t  =   1 ;  t  <  G . V ();  t ++ )   {              FlowNetwork  F  =   new   FlowNetwork ( G . V ());              for   ( Edge  e  :  G . edges ())   {                  int  v  =  e . either (),  w  =  e . other ( v );                 F . addEdge ( new   FlowEdge ( v ,  w ,  e . weight ()));                 F . addEdge ( new   FlowEdge ( w ,  v ,  e . weight ()));              }              FordFulkerson  maxflow  =   new   FordFulkerson ( F ,  s ,  t );             value  =   Math . min ( value ,  maxflow . value ());          }          if   ( Math . abs ( weight  -  value )   >
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
println
(
“Min cut weight = ”
 
+
 weight 
+
 
” , max flow value = ”
 
+
 value
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 GlobalMincut} data type.

     * 

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
EdgeWeightedGraph
 G 
=
 
new
 
EdgeWeightedGraph
(
in
);

        
GlobalMincut
 mc 
=
 
new
 
GlobalMincut
(
G
);

        
StdOut
.
print
(
“Min cut: ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( mc . cut ( v ))   StdOut . print ( v  +   " " );          }          StdOut . println ();          StdOut . println ( "Min cut weight = "   +  mc . weight ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GrahamScan.java edu/princeton/cs/algs4/GrahamScan.java /******************************************************************************  *  Compilation:  javac GrahamaScan.java  *  Execution:    java GrahamScan < input.txt  *  Dependencies: Point2D.java  *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt  *                https://algs4.cs.princeton.edu/99hull/kw1260.txt  *   *  Create points from standard input and compute the convex hull using  *  Graham scan algorithm.  *  *  May be floating-point issues if x- and y-coordinates are not integers.  *  *  % java GrahamScan < input100.txt   *  (7486.0, 422.0)  *  (29413.0, 596.0)  *  (32011.0, 3140.0)  *  (30875.0, 28560.0)  *  (28462.0, 32343.0)  *  (15731.0, 32661.0)  *  (822.0, 32301.0)  *  (823.0, 15895.0)  *  (1444.0, 10362.0)  *  (4718.0, 4451.0)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  *  The { @code  GrahamScan} data type provides methods for computing the   *  convex hull of a set of n points in the plane.

 *  

 *  The implementation uses the Graham-Scan convex hull algorithm.

 *  It runs in O(n log n) time in the worst case

 *  and uses O(n) extra memory.

 *  

 *  For additional documentation, see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
GrahamScan
 
{

    
private
 
Stack
< Point2D >
 hull 
=
 
new
 
Stack
< Point2D >
();

    
/**

     * Computes the convex hull of the specified array of points.

     *

     * 
@param
  points the array of points

     * 
@throws
 IllegalArgumentException if {
@code
 points} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if any entry in {
@code
 points[]} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if {
@code
 points.length} is {
@code
 0}

     */

    
public
 
GrahamScan
(
Point2D
[]
 points
)
 
{

        
if
 
(
points 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
if
 
(
points
.
length 
==
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“array is of length 0”
);

        
// defensive copy

        
int
 n 
=
 points
.
length
;

        
Point2D
[]
 a 
=
 
new
 
Point2D
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   ( points [ i ]   ==   null )                  throw   new   IllegalArgumentException ( "points["   +  i  +   "] is null" );             a [ i ]   =  points [ i ];          }          // preprocess so that a[0] has lowest y-coordinate; break ties by x-coordinate          // a[0] is an extreme point of the convex hull          // (alternatively, could do easily in linear time)          Arrays . sort ( a );          // sort by polar angle with respect to base point a[0],          // breaking ties by distance to a[0]          Arrays . sort ( a ,   1 ,  n ,  a [ 0 ]. polarOrder ());         hull . push ( a [ 0 ]);         // a[0] is first extreme point          // find index k1 of first point not equal to a[0]          int  k1 ;          for   ( k1  =   1 ;  k1  <  n ;  k1 ++ )              if   ( ! a [ 0 ]. equals ( a [ k1 ]))   break ;          if   ( k1  ==  n )   return ;          // all points equal          // find index k2 of first point not collinear with a[0] and a[k1]          int  k2 ;          for   ( k2  =  k1 + 1 ;  k2  <  n ;  k2 ++ )              if   ( Point2D . ccw ( a [ 0 ],  a [ k1 ],  a [ k2 ])   !=   0 )   break ;         hull . push ( a [ k2 - 1 ]);      // a[k2-1] is second extreme point          // Graham scan; note that a[n-1] is extreme point different from a[0]          for   ( int  i  =  k2 ;  i  <  n ;  i ++ )   {              Point2D  top  =  hull . pop ();              while   ( Point2D . ccw ( hull . peek (),  top ,  a [ i ])   <=   0 )   {                 top  =  hull . pop ();              }             hull . push ( top );             hull . push ( a [ i ]);          }          assert  isConvex ();      }      /**      * Returns the extreme points on the convex hull in counterclockwise order.      *      *  @return  the extreme points on the convex hull in counterclockwise order      */      public   Iterable < Point2D >
 hull
()
 
{

        
Stack
< Point2D >
 s 
=
 
new
 
Stack
< Point2D >
();

        
for
 
(
Point2D
 p 
:
 hull
)
 s
.
push
(
p
);

        
return
 s
;

    
}

    
// check that boundary of hull is strictly convex

    
private
 
boolean
 isConvex
()
 
{

        
int
 n 
=
 hull
.
size
();

        
if
 
(

<=   2 )   return   true ;          Point2D []  points  =   new   Point2D [ n ];          int  k  =   0 ;          for   ( Point2D  p  :  hull ())   {             points [ k ++ ]   =  p ;          }          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( Point2D . ccw ( points [ i ],  points [( i + 1 )   %  n ],  points [( i + 2 )   %  n ])   <=   0 )   {                  return   false ;              }          }          return   true ;      }     /**      * Unit tests the { @code  GrahamScan} data type.      * Reads in an integer { @code  n} and { @code  n} points (specified by      * their x– and y-coordinates) from standard input;

     * computes their convex hull; and prints out the points on the

     * convex hull to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        
Point2D
[]
 points 
=
 
new
 
Point2D
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  x  =   StdIn . readInt ();              int  y  =   StdIn . readInt ();             points [ i ]   =   new   Point2D ( x ,  y );          }          GrahamScan  graham  =   new   GrahamScan ( points );          for   ( Point2D  p  :  graham . hull ())              StdOut . println ( p );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GraphGenerator.java edu/princeton/cs/algs4/GraphGenerator.java /******************************************************************************  *  Compilation:  javac GraphGenerator.java  *  Execution:    java GraphGenerator V E  *  Dependencies: Graph.java  *  *  A graph generator.  *  *  For many more graph generators, see  *  http://networkx.github.io/documentation/latest/reference/generators.html  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  GraphGenerator} class provides static methods for creating  *  various graphs, including Erdos-Renyi random graphs, random bipartite  *  graphs, random k-regular graphs, and random rooted trees.  *  

 *  For additional documentation, see Section 4.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
GraphGenerator
 
{

    
private
 
static
 
final
 
class
 
Edge
 
implements
 
Comparable
< Edge >
 
{

        
private
 
int
 v
;

        
private
 
int
 w
;

        
private
 
Edge
(
int
 v
,
 
int
 w
)
 
{

            
if
 
(

<  w )   {                  this . v  =  v ;                  this . w  =  w ;              }              else   {                  this . v  =  w ;                  this . w  =  v ;              }          }          public   int  compareTo ( Edge  that )   {              if   ( this . v  <  that . v )   return   - 1 ;              if   ( this . v  >
 that
.
v
)
 
return
 
+
1
;

            
if
 
(
this
.

<  that . w )   return   - 1 ;              if   ( this . w  >
 that
.
w
)
 
return
 
+
1
;

            
return
 
0
;

        
}

    
}

    
// this class cannot be instantiated

    
private
 
GraphGenerator
()
 
{
 
}

    
/**

     * Returns a random simple graph containing {
@code
 V} vertices and {
@code
 E} edges.

     * 
@param
 V the number of vertices

     * 
@param
 E the number of vertices

     * 
@return
 a random simple graph on {
@code
 V} vertices, containing a total

     *     of {
@code
 E} edges

     * 
@throws
 IllegalArgumentException if no such simple graph exists

     */

    
public
 
static
 
Graph
 simple
(
int
 V
,
 
int
 E
)
 
{

        
if
 
(

>
 
(
long
)
 V
*
(
V

1
)
/
2
)
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<   0 )                  throw   new   IllegalArgumentException ( "Too few edges" );          Graph  G  =   new   Graph ( V );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
while
 
(
G
.
E
()
 
<  E )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );              Edge  e  =   new   Edge ( v ,  w );              if   (( v  !=  w )   &&   ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( v ,  w );              }          }          return  G ;      }      /**      * Returns a random simple graph on { @code  V} vertices, with an       * edge between any two vertices with probability { @code  p}. This is sometimes      * referred to as the Erdos-Renyi random graph model.      *  @param  V the number of vertices      *  @param  p the probability of choosing an edge      *  @return  a random simple graph on { @code  V} vertices, with an edge between      *     any two vertices with probability { @code  p}      *  @throws  IllegalArgumentException if probability is not between 0 and 1      */      public   static   Graph  simple ( int  V ,   double  p )   {          if   ( p  <   0.0   ||  p  >
 
1.0
)

            
throw
 
new
 
IllegalArgumentException
(
“Probability must be between 0 and 1”
);

        
Graph
 G 
=
 
new
 
Graph
(
V
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )              for   ( int  w  =  v + 1 ;  w  <  V ;  w ++ )                  if   ( StdRandom . bernoulli ( p ))                     G . addEdge ( v ,  w );          return  G ;      }      /**      * Returns the complete graph on { @code  V} vertices.      *  @param  V the number of vertices      *  @return  the complete graph on { @code  V} vertices      */      public   static   Graph  complete ( int  V )   {          return  simple ( V ,   1.0 );      }      /**      * Returns a complete bipartite graph on { @code  V1} and { @code  V2} vertices.      *  @param  V1 the number of vertices in one partition      *  @param  V2 the number of vertices in the other partition      *  @return  a complete bipartite graph on { @code  V1} and { @code  V2} vertices      *  @throws  IllegalArgumentException if probability is not between 0 and 1      */      public   static   Graph  completeBipartite ( int  V1 ,   int  V2 )   {          return  bipartite ( V1 ,  V2 ,  V1 * V2 );      }      /**      * Returns a random simple bipartite graph on { @code  V1} and { @code  V2} vertices      * with { @code  E} edges.      *  @param  V1 the number of vertices in one partition      *  @param  V2 the number of vertices in the other partition      *  @param  E the number of edges      *  @return  a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,      *    containing a total of { @code  E} edges      *  @throws  IllegalArgumentException if no such simple bipartite graph exists      */      public   static   Graph  bipartite ( int  V1 ,   int  V2 ,   int  E )   {          if   ( E  >
 
(
long
)
 V1
*
V2
)
 
throw
 
new
 
IllegalArgumentException
(
“Too many edges”
);

        
if
 
(

<   0 )              throw   new   IllegalArgumentException ( "Too few edges" );          Graph  G  =   new   Graph ( V1  +  V2 );          int []  vertices  =   new   int [ V1  +  V2 ];          for   ( int  i  =   0 ;  i  <  V1  +  V2 ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );         SET < Edge >
 set 
=
 
new
 SET
< Edge >
();

        
while
 
(
G
.
E
()
 
<  E )   {              int  i  =   StdRandom . uniform ( V1 );              int  j  =  V1  +   StdRandom . uniform ( V2 );              Edge  e  =   new   Edge ( vertices [ i ],  vertices [ j ]);              if   ( ! set . contains ( e ))   {                 set . add ( e );                 G . addEdge ( vertices [ i ],  vertices [ j ]);              }          }          return  G ;      }      /**      * Returns a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,      * containing each possible edge with probability { @code  p}.      *  @param  V1 the number of vertices in one partition      *  @param  V2 the number of vertices in the other partition      *  @param  p the probability that the graph contains an edge with one endpoint in either side      *  @return  a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,      *    containing each possible edge with probability { @code  p}      *  @throws  IllegalArgumentException if probability is not between 0 and 1      */      public   static   Graph  bipartite ( int  V1 ,   int  V2 ,   double  p )   {          if   ( p  <   0.0   ||  p  >
 
1.0
)

            
throw
 
new
 
IllegalArgumentException
(
“Probability must be between 0 and 1”
);

        
int
[]
 vertices 
=
 
new
 
int
[
V1 
+
 V2
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V1  +  V2 ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          Graph  G  =   new   Graph ( V1  +  V2 );          for   ( int  i  =   0 ;  i  <  V1 ;  i ++ )              for   ( int  j  =   0 ;  j  <  V2 ;  j ++ )                  if   ( StdRandom . bernoulli ( p ))                     G . addEdge ( vertices [ i ],  vertices [ V1 + j ]);          return  G ;      }      /**      * Returns a path graph on { @code  V} vertices.      *  @param  V the number of vertices in the path      *  @return  a path graph on { @code  V} vertices      */      public   static   Graph  path ( int  V )   {          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }          return  G ;      }      /**      * Returns a complete binary tree graph on { @code  V} vertices.      *  @param  V the number of vertices in the binary tree      *  @return  a complete binary tree graph on { @code  V} vertices      */      public   static   Graph  binaryTree ( int  V )   {          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [( i - 1 ) / 2 ]);          }          return  G ;      }      /**      * Returns a cycle graph on { @code  V} vertices.      *  @param  V the number of vertices in the cycle      *  @return  a cycle graph on { @code  V} vertices      */      public   static   Graph  cycle ( int  V )   {          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }         G . addEdge ( vertices [ V - 1 ],  vertices [ 0 ]);          return  G ;      }      /**      * Returns an Eulerian cycle graph on { @code  V} vertices.      *      *  @param   V the number of vertices in the cycle      *  @param   E the number of edges in the cycle      *  @return  a graph that is an Eulerian cycle on { @code  V} vertices      *         and { @code  E} edges      *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E <= 0}      */      public   static   Graph  eulerianCycle ( int  V ,   int  E )   {          if   ( E  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one edge" );          if   ( V  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one vertex" );          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ E ];          for   ( int  i  =   0 ;  i  <  E ;  i ++ )             vertices [ i ]   =   StdRandom . uniform ( V );          for   ( int  i  =   0 ;  i  <  E - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }         G . addEdge ( vertices [ E - 1 ],  vertices [ 0 ]);          return  G ;      }      /**      * Returns an Eulerian path graph on { @code  V} vertices.      *      *  @param   V the number of vertices in the path      *  @param   E the number of edges in the path      *  @return  a graph that is an Eulerian path on { @code  V} vertices      *         and { @code  E} edges      *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E < 0}      */      public   static   Graph  eulerianPath ( int  V ,   int  E )   {          if   ( E  <   0 )              throw   new   IllegalArgumentException ( "negative number of edges" );          if   ( V  <=   0 )              throw   new   IllegalArgumentException ( "An Eulerian path must have at least one vertex" );          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ E + 1 ];          for   ( int  i  =   0 ;  i  <  E + 1 ;  i ++ )             vertices [ i ]   =   StdRandom . uniform ( V );          for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }          return  G ;      }      /**      * Returns a wheel graph on { @code  V} vertices.      *  @param  V the number of vertices in the wheel      *  @return  a wheel graph on { @code  V} vertices: a single vertex connected to      *     every vertex in a cycle on { @code  V-1} vertices      */      public   static   Graph  wheel ( int  V )   {          if   ( V  <=   1 )   throw   new   IllegalArgumentException ( "Number of vertices must be at least 2" );          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          // simple cycle on V-1 vertices          for   ( int  i  =   1 ;  i  <  V - 1 ;  i ++ )   {             G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);          }         G . addEdge ( vertices [ V - 1 ],  vertices [ 1 ]);          // connect vertices[0] to every vertex on cycle          for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {             G . addEdge ( vertices [ 0 ],  vertices [ i ]);          }          return  G ;      }      /**      * Returns a star graph on { @code  V} vertices.      *  @param  V the number of vertices in the star      *  @return  a star graph on { @code  V} vertices: a single vertex connected to      *     every other vertex      */      public   static   Graph  star ( int  V )   {          if   ( V  <=   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be at least 1" );          Graph  G  =   new   Graph ( V );          int []  vertices  =   new   int [ V ];          for   ( int  i  =   0 ;  i  <  V ;  i ++ )             vertices [ i ]   =  i ;          StdRandom . shuffle ( vertices );          // connect vertices[0] to every other vertex          for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {             G . addEdge ( vertices [ 0 ],  vertices [ i ]);          }          return  G ;      }      /**      * Returns a uniformly random { @code  k}-regular graph on { @code  V} vertices      * (not necessarily simple). The graph is simple with probability only about e^(-k^2/4),      * which is tiny when k = 14.      *      *  @param  V the number of vertices in the graph      *  @param  k degree of each vertex      *  @return  a uniformly random { @code  k}-regular graph on { @code  V} vertices.      */      public   static   Graph  regular ( int  V ,   int  k )   {          if   ( V * k  %   2   !=   0 )   throw   new   IllegalArgumentException ( "Number of vertices * k must be even" );          Graph  G  =   new   Graph ( V );          // create k copies of each vertex          int []  vertices  =   new   int [ V * k ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              for   ( int  j  =   0 ;  j  <  k ;  j ++ )   {                 vertices [ v  +  V * j ]   =  v ;              }          }          // pick a random perfect matching          StdRandom . shuffle ( vertices );          for   ( int  i  =   0 ;  i  <  V * k / 2 ;  i ++ )   {             G . addEdge ( vertices [ 2 * i ],  vertices [ 2 * i  +   1 ]);          }          return  G ;      }      // http://www.proofwiki.org/wiki/Labeled_Tree_from_Prüfer_Sequence      // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.6484&rep=rep1&type=pdf      /**      * Returns a uniformly random tree on { @code  V} vertices.      * This algorithm uses a Prufer sequence and takes time proportional to V log V.

     * 
@param
 V the number of vertices in the tree

     * 
@return
 a uniformly random tree on {
@code
 V} vertices

     */

    
public
 
static
 
Graph
 tree
(
int
 V
)
 
{

        
Graph
 G 
=
 
new
 
Graph
(
V
);

        
// special case

        
if
 
(

==
 
1
)
 
return
 G
;

        
// Cayley’s theorem: there are V^(V-2) labeled trees on V vertices

        
// Prufer sequence: sequence of V-2 values between 0 and V-1

        
// Prufer’s proof of Cayley’s theorem: Prufer sequences are in 1-1

        
// with labeled trees on V vertices

        
int
[]
 prufer 
=
 
new
 
int
[
V

2
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  V - 2 ;  i ++ )             prufer [ i ]   =   StdRandom . uniform ( V );          // degree of vertex v = 1 + number of times it appers in Prufer sequence          int []  degree  =   new   int [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )             degree [ v ]   =   1 ;          for   ( int  i  =   0 ;  i  <  V - 2 ;  i ++ )             degree [ prufer [ i ]] ++ ;          // pq contains all vertices of degree 1          MinPQ < Integer >
 pq 
=
 
new
 
MinPQ
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )              if   ( degree [ v ]   ==   1 )  pq . insert ( v );          // repeatedly delMin() degree 1 vertex that has the minimum index          for   ( int  i  =   0 ;  i  <  V - 2 ;  i ++ )   {              int  v  =  pq . delMin ();             G . addEdge ( v ,  prufer [ i ]);             degree [ v ] -- ;             degree [ prufer [ i ]] -- ;              if   ( degree [ prufer [ i ]]   ==   1 )  pq . insert ( prufer [ i ]);          }         G . addEdge ( pq . delMin (),  pq . delMin ());          return  G ;      }      /**      * Unit tests the { @code  GraphGenerator} library.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  V  =   Integer . parseInt ( args [ 0 ]);          int  E  =   Integer . parseInt ( args [ 1 ]);          int  V1  =  V / 2 ;          int  V2  =  V  -  V1 ;          StdOut . println ( "complete graph" );          StdOut . println ( complete ( V ));          StdOut . println ();          StdOut . println ( "simple" );          StdOut . println ( simple ( V ,  E ));          StdOut . println ();          StdOut . println ( "Erdos-Renyi" );          double  p  =   ( double )  E  /   ( V * ( V - 1 ) / 2.0 );          StdOut . println ( simple ( V ,  p ));          StdOut . println ();          StdOut . println ( "complete bipartite" );          StdOut . println ( completeBipartite ( V1 ,  V2 ));          StdOut . println ();          StdOut . println ( "bipartite" );          StdOut . println ( bipartite ( V1 ,  V2 ,  E ));          StdOut . println ();          StdOut . println ( "Erdos Renyi bipartite" );          double  q  =   ( double )  E  /   ( V1 * V2 );          StdOut . println ( bipartite ( V1 ,  V2 ,  q ));          StdOut . println ();          StdOut . println ( "path" );          StdOut . println ( path ( V ));          StdOut . println ();          StdOut . println ( "cycle" );          StdOut . println ( cycle ( V ));          StdOut . println ();          StdOut . println ( "binary tree" );          StdOut . println ( binaryTree ( V ));          StdOut . println ();          StdOut . println ( "tree" );          StdOut . println ( tree ( V ));          StdOut . println ();          StdOut . println ( "4-regular" );          StdOut . println ( regular ( V ,   4 ));          StdOut . println ();          StdOut . println ( "star" );          StdOut . println ( star ( V ));          StdOut . println ();          StdOut . println ( "wheel" );          StdOut . println ( wheel ( V ));          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Graph.java edu/princeton/cs/algs4/Graph.java /******************************************************************************  *  Compilation:  javac Graph.java          *  Execution:    java Graph input.txt  *  Dependencies: Bag.java Stack.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *                https://algs4.cs.princeton.edu/41graph/largeG.txt  *  *  A graph, implemented using an array of sets.  *  Parallel edges and self-loops allowed.  *  *  % java Graph tinyG.txt  *  13 vertices, 13 edges   *  0: 6 2 1 5   *  1: 0   *  2: 0   *  3: 5 4   *  4: 5 6 3   *  5: 3 4 0   *  6: 0 4   *  7: 8   *  8: 7   *  9: 11 10 12   *  10: 9   *  11: 9 12   *  12: 11 9   *  *  % java Graph mediumG.txt  *  250 vertices, 1273 edges   *  0: 225 222 211 209 204 202 191 176 163 160 149 114 97 80 68 59 58 49 44 24 15   *  1: 220 203 200 194 189 164 150 130 107 72   *  2: 141 110 108 86 79 51 42 18 14   *  ...  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  Graph} class represents an undirected graph of vertices  *  named 0 through V – 1.

 *  It supports the following two primary operations: add an edge to the graph,

 *  iterate over all of the vertices adjacent to a vertex. It also provides

 *  methods for returning the degree of a vertex, the number of vertices

 *  V in the graph, and the number of edges E in the graph.

 *  Parallel edges and self-loops are permitted.

 *  By convention, a self-loop vv appears in the

 *  adjacency list of v twice and contributes two to the degree

 *  of v.

 *  

 *  This implementation uses an adjacency-lists representation, which

 *  is a vertex-indexed array of {
@link
 Bag} objects.

 *  It uses Θ(E + V) space, where E is

 *  the number of edges and V is the number of vertices.

 *  All instance methods take Θ(1) time. (Though, iterating over

 *  the vertices returned by {
@link
 #adj(int)} takes time proportional

 *  to the degree of the vertex.)

 *  Constructing an empty graph with V vertices takes

 *  Θ(V) time; constructing a graph with E edges

 *  and V vertices takes Θ(E + V) time. 

 *  

 *  For additional documentation, see

 *  Section 4.1

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Graph
 
{

    
private
 
static
 
final
 
String
 NEWLINE 
=
 
System
.
getProperty
(
“line.separator”
);

    
private
 
final
 
int
 V
;

    
private
 
int
 E
;

    
private
 
Bag
< Integer >
[]
 adj
;

    

    
/**

     * Initializes an empty graph with {
@code
 V} vertices and 0 edges.

     * param V the number of vertices

     *

     * 
@param
  V number of vertices

     * 
@throws
 IllegalArgumentException if {
@code
 V < 0}      */      public   Graph ( int  V )   {          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );          this . V  =  V ;          this . E  =   0 ;         adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             adj [ v ]   =   new   Bag < Integer >
();

        
}

    
}

    
/**  

     * Initializes a graph from the specified input stream.

     * The format is the number of vertices V,

     * followed by the number of edges E,

     * followed by E pairs of vertices, with each entry separated by whitespace.

     *

     * 
@param
  in the input stream

     * 
@throws
 IllegalArgumentException if {
@code
 in} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if the endpoints of any edge are not in prescribed range

     * 
@throws
 IllegalArgumentException if the number of vertices or edges is negative

     * 
@throws
 IllegalArgumentException if the input stream is in the wrong format

     */

    
public
 
Graph
(
In
 in
)
 
{

        
if
 
(
in 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            
this
.

=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Graph must be nonnegative" );             adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

            
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {                 adj [ v ]   =   new   Bag < Integer >
();

            
}

            
int
 E 
=
 in
.
readInt
();

            
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "number of edges in a Graph must be nonnegative" );              for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {                  int  v  =  in . readInt ();                  int  w  =  in . readInt ();                 validateVertex ( v );                 validateVertex ( w );                 addEdge ( v ,  w );                }          }          catch   ( NoSuchElementException  e )   {              throw   new   IllegalArgumentException ( "invalid input format in Graph constructor" ,  e );          }      }      /**      * Initializes a new graph that is a deep copy of { @code  G}.      *      *  @param   G the graph to copy      *  @throws  IllegalArgumentException if { @code  G} is { @code  null}      */      public   Graph ( Graph  G )   {          this . V  =  G . V ();          this . E  =  G . E ();          if   ( V  <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );          // update adjacency lists         adj  =   ( Bag < Integer >
[])
 
new
 
Bag
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             adj [ v ]   =   new   Bag < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              // reverse so that adjacency list is in same order as original              Stack < Integer >
 reverse 
=
 
new
 
Stack
< Integer >
();

            
for
 
(
int
 w 
:
 G
.
adj
[
v
])
 
{

                reverse
.
push
(
w
);

            
}

            
for
 
(
int
 w 
:
 reverse
)
 
{

                adj
[
v
].
add
(
w
);

            
}

        
}

    
}

    
/**

     * Returns the number of vertices in this graph.

     *

     * 
@return
 the number of vertices in this graph

     */

    
public
 
int
 V
()
 
{

        
return
 V
;

    
}

    
/**

     * Returns the number of edges in this graph.

     *

     * 
@return
 the number of edges in this graph

     */

    
public
 
int
 E
()
 
{

        
return
 E
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Adds the undirected edge v-w to this graph.

     *

     * 
@param
  v one vertex in the edge

     * 
@param
  w the other vertex in the edge

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= v < V} and { @code  0 <= w < V}      */      public   void  addEdge ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );         E ++ ;         adj [ v ]. add ( w );         adj [ w ]. add ( v );      }      /**      * Returns the vertices adjacent to vertex { @code  v}.      *      *  @param   v the vertex      *  @return  the vertices adjacent to vertex { @code  v}, as an iterable      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   Iterable < Integer >
 adj
(
int
 v
)
 
{

        validateVertex
(
v
);

        
return
 adj
[
v
];

    
}

    
/**

     * Returns the degree of vertex {
@code
 v}.

     *

     * 
@param
  v the vertex

     * 
@return
 the degree of vertex {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  degree ( int  v )   {         validateVertex ( v );          return  adj [ v ]. size ();      }      /**      * Returns a string representation of this graph.      *      *  @return  the number of vertices V, followed by the number of edges E,

     *         followed by the V adjacency lists

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(

+
 
” vertices, ”
 
+
 E 
+
 
” edges ”
 
+
 NEWLINE
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {             s . append ( v  +   ": " );              for   ( int  w  :  adj [ v ])   {                 s . append ( w  +   " " );              }             s . append ( NEWLINE );          }          return  s . toString ();      }      /**      * Unit tests the { @code  Graph} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          Graph  G  =   new   Graph ( in );          StdOut . println ( G );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GrayscalePicture.java edu/princeton/cs/algs4/GrayscalePicture.java /******************************************************************************  *  Compilation:  javac GrayscalePicture.java  *  Execution:    java GrayscalePicture imagename  *  Dependencies: none  *  *  Data type for manipulating individual pixels of a grayscale image. The  *  original image can be read from a file in JPEG, GIF, or PNG format, or the  *  user can create a blank image of a given dimension. Includes methods for  *  displaying the image in a window on the screen or saving to a file.  *  *  % java GrayscalePicture mandrill  *  *  Remarks  *  -------  *   - pixel (x, y) is column x and row y, where (0, 0) is upper left  *  *   - uses BufferedImage.TYPE_INT_RGB because BufferedImage.TYPE_BYTE_GRAY  *     seems to do some undesirable olor correction when calling getRGB() and  *     setRGB()  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . Color ; import  java . awt . FileDialog ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . KeyEvent ; import  java . awt . image . BufferedImage ; import  java . io . File ; import  java . io . IOException ; import  java . net . URL ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . JPanel ; import  javax . swing . KeyStroke ; /**  *  This class provides methods for manipulating individual pixels of  *  a grayscale image.  *  The original image can be read from a { @code  PNG}, { @code  GIF},  *  or { @code  JPEG} file or the user can create a blank image of a given dimension.  *  This class includes methods for displaying the image in a window on  *  the screen or saving it to a file.  *  

 *  Pixel (colrow) is column col and row row.

 *  By default, the origin (0, 0) is the pixel in the top-left corner,

 *  which is a common convention in image processing.

 *  The method {
@link
 #setOriginLowerLeft()} change the origin to the lower left.

 *  

 *  The {
@code
 get()} and {
@code
 set()} methods use {
@link
 Color} objects to get

 *  or set the color of the specified pixel. The {
@link
 Color} objects are converted

 *  to grayscale if they have different values for the R, G, and B channels.

 *  The {
@code
 getGrayscale()} and {
@code
 setGrayscale()} methods use an

 *  8-bit {
@code
 int} to encode the grayscale value, thereby avoiding the need to

 *  create temporary {
@code
 Color} objects.

 *  

 *  A W-by-H picture uses ~ 4 W H bytes of memory,

 *  since the color of each pixel is encoded as a 32-bit int

 *  (even though, in principle, only ~ W H bytes are needed).

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *  See {
@link
 Picture} for a version that supports 32-bit RGB color images.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
GrayscalePicture
 
implements
 
ActionListener
 
{

    
private
 
BufferedImage
 image
;
               
// the rasterized image

    
private
 
JFrame
 frame
;
                      
// on-screen view

    
private
 
String
 filename
;
                   
// name of file

    
private
 
boolean
 isOriginUpperLeft 
=
 
true
;
  
// location of origin

    
private
 
final
 
int
 width
,
 height
;
           
// width and height

   
/**

     * Creates a {
@code
 width}-by-{
@code
 height} picture, with {
@code
 width} columns

     * and {
@code
 height} rows, where each pixel is black.

     *

     * 
@param
 width the width of the picture

     * 
@param
 height the height of the picture

     * 
@throws
 IllegalArgumentException if {
@code
 width} is negative

     * 
@throws
 IllegalArgumentException if {
@code
 height} is negative

     */

    
public
 
GrayscalePicture
(
int
 width
,
 
int
 height
)
 
{

        
if
 
(
width  
<   0 )   throw   new   IllegalArgumentException ( "width must be non-negative" );          if   ( height  <   0 )   throw   new   IllegalArgumentException ( "height must be non-negative" );          this . width   =  width ;          this . height  =  height ;         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );      }     /**      * Creates a new grayscale picture that is a deep copy of the argument picture.      *      *  @param   picture the picture to copy      *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}      */      public   GrayscalePicture ( GrayscalePicture  picture )   {          if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );         width   =  picture . width ();         height  =  picture . height ();         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );         filename  =  picture . filename ;         isOriginUpperLeft  =  picture . isOriginUpperLeft ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                 image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));      }     /**      * Creates a grayscale picture by reading an image from a file or URL.      *      *  @param   name the name of the file ( , .gif, or  ) or URL.      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   GrayscalePicture ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          this . filename  =  name ;          try   {              // try to read from file in working directory              File  file  =   new   File ( name );              if   ( file . isFile ())   {                 image  =   ImageIO . read ( file );              }              else   {                  // resource relative to .class file                 URL url  =  getClass (). getResource ( name );                  // resource relative to classloader root                  if   ( url  ==   null )   {                     url  =  getClass (). getClassLoader (). getResource ( name );                  }                        // or URL from web                  if   ( url  ==   null )   {                     url  =   new  URL ( name );                  }                          image  =   ImageIO . read ( url );              }              if   ( image  ==   null )   {                  throw   new   IllegalArgumentException ( "could not read image: "   +  name );              }             width   =  image . getWidth ( null );             height  =  image . getHeight ( null );              // convert to grayscale inplace              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {                      Color  color  =   new   Color ( image . getRGB ( col ,  row ));                      Color  gray  =  toGray ( color );                     image . setRGB ( col ,  row ,  gray . getRGB ());                  }              }          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );          }      }       // Returns a grayscale version of the given color as a Color object.      private   static   Color  toGray ( Color  color )   {          int  r  =  color . getRed ();          int  g  =  color . getGreen ();          int  b  =  color . getBlue ();          int  y  =   ( int )   ( Math . round ( 0.299 * r  +   0.587 * g  +   0.114 * b ));          return   new   Color ( y ,  y ,  y );      }     /**      * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},      * { @link  JFrame} or other GUI widget.      *      *  @return  the { @code  JLabel}      */      public   JLabel  getJLabel ()   {          if   ( image  ==   null )   return   null ;           // no image available          ImageIcon  icon  =   new   ImageIcon ( image );          return   new   JLabel ( icon );      }     /**      * Sets the origin to be the upper left pixel. This is the default.      */      public   void  setOriginUpperLeft ()   {         isOriginUpperLeft  =   true ;      }     /**      * Sets the origin to be the lower left pixel.      */      public   void  setOriginLowerLeft ()   {         isOriginUpperLeft  =   false ;      }     /**      * Displays the picture in a window on the screen.      */      public   void  show ()   {          // create the GUI for viewing the image if needed          if   ( frame  ==   null )   {             frame  =   new   JFrame ();              JMenuBar  menuBar  =   new   JMenuBar ();              JMenu  menu  =   new   JMenu ( "File" );             menuBar . add ( menu );              JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );             menuItem1 . addActionListener ( this );              // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)             menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                       Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));             menu . add ( menuItem1 );             frame . setJMenuBar ( menuBar );             frame . setContentPane ( getJLabel ());              // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);             frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );              if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );              else                   frame . setTitle ( filename );             frame . setResizable ( false );             frame . pack ();             frame . setVisible ( true );          }          // draw         frame . repaint ();      }     /**      * Returns the height of the picture.      *      *  @return  the height of the picture (in pixels)      */      public   int  height ()   {          return  height ;      }     /**      * Returns the width of the picture.      *      *  @return  the width of the picture (in pixels)      */      public   int  width ()   {          return  width ;      }      private   void  validateRowIndex ( int  row )   {          if   ( row  <   0   ||  row  >=
 height
())

            
throw
 
new
 
IllegalArgumentException
(
“row index must be between 0 and ”
 
+
 
(
height
()
 

 
1
)
 
+
 
“: ”
 
+
 row
);

    
}

    
private
 
void
 validateColumnIndex
(
int
 col
)
 
{

        
if
 
(
col 
<   0   ||  col  >=
 width
())

            
throw
 
new
 
IllegalArgumentException
(
“column index must be between 0 and ”
 
+
 
(
width
()
 

 
1
)
 
+
 
“: ”
 
+
 col
);

    
}

    
private
 
void
 validateGrayscaleValue
(
int
 gray
)
 
{

        
if
 
(
gray 
<   0   ||  gray  >=
 
256
)

            
throw
 
new
 
IllegalArgumentException
(
“grayscale value must be between 0 and 255”
);

    
}

   
/**

     * Returns the grayscale value of pixel ({
@code
 col}, {
@code
 row}) as a {
@link
 java.awt.Color}.

     *

     * 
@param
 col the column index

     * 
@param
 row the row index

     * 
@return
 the grayscale value of pixel ({
@code
 col}, {
@code
 row})

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= col < width} and { @code  0 <= row < height}      */      public   Color  get ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          Color  color  =   new   Color ( image . getRGB ( col ,  row ));          return  toGray ( color );      }     /**      * Returns the grayscale value of pixel ({ @code  col}, { @code  row}) as an { @code  int}      * between 0 and 255.      * Using this method can be more efficient than { @link  #get(int, int)} because      * it does not create a { @code  Color} object.      *      *  @param  col the column index      *  @param  row the row index      *  @return  the 8-bit integer representation of the grayscale value of pixel ({ @code  col}, { @code  row})      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   int  getGrayscale ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row )   &   0xFF ;          else                     return  image . getRGB ( col ,  height  -  row  -   1 )   &   0xFF ;      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value.      *      *  @param  col the column index      *  @param  row the row index      *  @param  color the color (converts to grayscale if color is not a shade of gray)      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  set ( int  col ,   int  row ,   Color  color )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );          Color  gray  =  toGray ( color );         image . setRGB ( col ,  row ,  gray . getRGB ());      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value      * between 0 and 255.      *      *  @param  col the column index      *  @param  row the row index      *  @param  gray the 8-bit integer representation of the grayscale value      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   void  setGrayscale ( int  col ,   int  row ,   int  gray )   {         validateColumnIndex ( col );         validateRowIndex ( row );         validateGrayscaleValue ( gray );          int  rgb  =  gray  |   ( gray  <<   8 )   |   ( gray  <<   16 );          if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );          else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );      }     /**      * Returns true if this picture is equal to the argument picture.      *      *  @param  other the other picture      *  @return  { @code  true} if this picture is the same dimension as { @code  other}      *         and if all pixels have the same color; { @code  false} otherwise      */      public   boolean  equals ( Object  other )   {          if   ( other  ==   this )   return   true ;          if   ( other  ==   null )   return   false ;          if   ( other . getClass ()   !=   this . getClass ())   return   false ;          GrayscalePicture  that  =   ( GrayscalePicture )  other ;          if   ( this . width ()    !=  that . width ())    return   false ;          if   ( this . height ()   !=  that . height ())   return   false ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                  if   ( this . getGrayscale ( col ,  row )   !=  that . getGrayscale ( col ,  row ))   return   false ;          return   true ;      }     /**      * Returns a string representation of this picture.      * The result is a width-by-height matrix of pixels,

     * where the grayscale value of a pixel is an integer between 0 and 255.

     *

     * 
@return
 a string representation of this picture

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 sb 
=
 
new
 
StringBuilder
();

        sb
.
append
(
width 
+
“-by-”
 
+
 height 
+
 
” grayscale picture (grayscale values given in hex)\n”
);

        
for
 
(
int
 row 
=
 
0
;
 row 
<  height ;  row ++ )   {              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  int  gray  =   0 ;                  if   ( isOriginUpperLeft )  gray  =   0xFF   &  image . getRGB ( col ,  row );                  else                    gray  =   0xFF   &  image . getRGB ( col ,  height  -  row  -   1 );                 sb . append ( String . format ( "%3d " ,  gray ));              }             sb . append ( "\n" );          }          return  sb . toString (). trim ();      }      /**      * This operation is not supported because pictures are mutable.      *      *  @return  does not return a value      *  @throws  UnsupportedOperationException if called      */      public   int  hashCode ()   {          throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );      }     /**      * Saves the picture to a file in either PNG or JPEG format.      * The filetype extension must be either   or  .      *      *  @param  name the name of the file      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   void  save ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         save ( new   File ( name ));         filename  =  name ;      }     /**      * Saves the picture to a file in a PNG or JPEG image format.      *      *  @param   file the file      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   void  save ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         filename  =  file . getName ();          if   ( frame  !=   null )  frame . setTitle ( filename );          String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );          if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {              try   {                  ImageIO . write ( image ,  suffix ,  file );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }          }          else   {              System . out . println ( "Error: filename must end in   or  " );          }      }     /**      * Opens a save dialog box when the user selects "Save As" from the menu.      */     @ Override      public   void  actionPerformed ( ActionEvent  e )   {          FileDialog  chooser  =   new   FileDialog ( frame ,                               "Use a   or   extension" ,   FileDialog . SAVE );         chooser . setVisible ( true );          if   ( chooser . getFile ()   !=   null )   {             save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());          }      }     /**      * Unit tests this { @code  Picture} data type.      * Reads a picture specified by the command-line argument,      * and shows it in a window on the screen.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          GrayscalePicture  picture  =   new   GrayscalePicture ( args [ 0 ]);          StdOut . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());          GrayscalePicture  copy  =   new   GrayscalePicture ( picture );         picture . show ();         copy . show ();          while   ( ! StdIn . isEmpty ())   {              int  row  =   StdIn . readInt ();              int  col  =   StdIn . readInt ();              int  gray  =   StdIn . readInt ();             picture . setGrayscale ( row ,  col ,  gray );              StdOut . println ( picture . get ( row ,  col ));              StdOut . println ( picture . getGrayscale ( row ,  col ));          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/GREP.java edu/princeton/cs/algs4/GREP.java /******************************************************************************  *  Compilation:  javac GREP.java  *  Execution:    java GREP regexp < input.txt  *  Dependencies: NFA.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/54regexp/tinyL.txt  *  *  This program takes an RE as a command-line argument and prints  *  the lines from standard input having some substring that  *  is in the language described by the RE.   *  *  % more tinyL.txt  *  AC  *  AD  *  AAA  *  ABD  *  ADD  *  BCD  *  ABCCBD  *  BABAAA  *  BABBAAA  *  *  %  java GREP "(A*B|AC)D" < tinyL.txt  *  ABD  *  ABCCBD  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  GREP} class provides a client for reading in a sequence of  *  lines from standard input and printing to standard output those lines  *  that contain a substring matching a specified regular expression.  *  

 *  For additional documentation, see Section 3.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 GREP 
{

    
// do not instantiate

    
private
 GREP
()
 
{
 
}

    
/**

     * Interprets the command-line argument as a regular expression

     * (supporting closure, binary or, parentheses, and wildcard)

     * reads in lines from standard input; writes to standard output

     * those lines that contain a substring matching the regular

     * expression.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{
 

        
String
 regexp 
=
 
“(.*”
 
+
 args
[
0
]
 
+
 
“.*)”
;

        NFA nfa 
=
 
new
 NFA
(
regexp
);

        
while
 
(
StdIn
.
hasNextLine
())
 
{
 

            
String
 line 
=
 
StdIn
.
readLine
();

            
if
 
(
nfa
.
recognizes
(
line
))
 
{

                
StdOut
.
println
(
line
);

            
}

        
}

    
}
 

}
 

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Heap.java
edu/princeton/cs/algs4/Heap.java
/******************************************************************************

 *  Compilation:  javac Heap.java

 *  Execution:    java Heap < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/24pq/tiny.txt  *                https://algs4.cs.princeton.edu/24pq/words3.txt  *    *  Sorts a sequence of strings from standard input using heapsort.  *  *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Heap < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *  *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *  *  % java Heap < words3.txt  *  all bad bed bug dad ... yes yet zoo   [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Heap} class provides a static method to sort an array  *  using heapsort.

 *  

 *  This implementation takes Θ(n log n) time

 *  to sort any array of length n (assuming comparisons

 *  take constant time). It makes at most 

 *  2 n log2 n compares.

 *  

 *  This sorting algorithm is not stable.

 *  It uses Θ(1) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Heap
 
{

    
// This class should not be instantiated.

    
private
 
Heap
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 pq the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 pq
)
 
{

        
int
 n 
=
 pq
.
length
;

        
for
 
(
int
 k 
=
 n
/
2
;
 k 
>=
 
1
;
 k

)

            sink
(
pq
,
 k
,
 n
);

        
while
 
(

>
 
1
)
 
{

            exch
(
pq
,
 
1
,
 n

);

            sink
(
pq
,
 
1
,
 n
);

        
}

    
}

   
/***************************************************************************

    * Helper functions to restore the heap invariant.

    ***************************************************************************/

    
private
 
static
 
void
 sink
(
Comparable
[]
 pq
,
 
int
 k
,
 
int
 n
)
 
{

        
while
 
(
2
*

<=  n )   {              int  j  =   2 * k ;              if   ( j  <  n  &&  less ( pq ,  j ,  j + 1 ))  j ++ ;              if   ( ! less ( pq ,  k ,  j ))   break ;             exch ( pq ,  k ,  j );             k  =  j ;          }      }     /***************************************************************************     * Helper functions for comparisons and swaps.     * Indices are "off-by-one" to support 1-based indexing.     ***************************************************************************/      private   static   boolean  less ( Comparable []  pq ,   int  i ,   int  j )   {          return  pq [ i - 1 ]. compareTo ( pq [ j - 1 ])   <   0 ;      }      private   static   void  exch ( Object []  pq ,   int  i ,   int  j )   {          Object  swap  =  pq [ i - 1 ];         pq [ i - 1 ]   =  pq [ j - 1 ];         pq [ j - 1 ]   =  swap ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; heapsorts them;       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Heap . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/HexDump.java edu/princeton/cs/algs4/HexDump.java /******************************************************************************  *  Compilation:  javac HexDump.java  *  Execution:    java HexDump < file  *  Dependencies: BinaryStdIn.java StdOut.java  *  Data file:    https://algs4.cs.princeton.edu/55compression/abra.txt  *    *  Reads in a binary file and writes out the bytes in hex, 16 per line.  *  *  % more abra.txt  *  ABRACADABRA!  *  *  % java HexDump 16 < abra.txt  *  41 42 52 41 43 41 44 41 42 52 41 21  *  96 bits  *  *  *  Remark  *  --------------------------  *   - Similar to the Unix utilities od (octal dump) or hexdump (hexadecimal dump).  *  *  % od -t x1 < abra.txt   *  0000000 41 42 52 41 43 41 44 41 42 52 41 21  *  0000014  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  HexDump} class provides a client for displaying the contents  *  of a binary file in hexadecimal.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  See also {
@link
 BinaryDump} and {
@link
 PictureDump}.

 *  For more full-featured versions, see the Unix utilities

 *  {
@code
 od} (octal dump) and {
@code
 hexdump} (hexadecimal dump).

 *  

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
HexDump
 
{

    
// Do not instantiate.

    
private
 
HexDump
()
 
{
 
}

    
/**

     * Reads in a sequence of bytes from standard input and writes

     * them to standard output using hexademical notation, k hex digits

     * per line, where k is given as a command-line integer (defaults

     * to 16 if no integer is specified); also writes the number

     * of bits.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 bytesPerLine 
=
 
16
;

        
if
 
(
args
.
length 
==
 
1
)
 
{

            bytesPerLine 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
}

        
int
 i
;

        
for
 
(

=
 
0
;
 
!
BinaryStdIn
.
isEmpty
();
 i
++
)
 
{

            
if
 
(
bytesPerLine 
==
 
0
)
 
{

                
BinaryStdIn
.
readChar
();

                
continue
;

            
}

            
if
 
(

==
 
0
)
 
StdOut
.
printf
(
“”
);

            
else
 
if
 
(

%
 bytesPerLine 
==
 
0
)
 
StdOut
.
printf
(
“\n”
,
 i
);

            
else
 
StdOut
.
print
(
” ”
);

            
char
 c 
=
 
BinaryStdIn
.
readChar
();

            
StdOut
.
printf
(
“%02x”
,
 c 
&
 
0xff
);

        
}

        
if
 
(
bytesPerLine 
!=
 
0
)
 
StdOut
.
println
();

        
StdOut
.
println
((
i
*
8
)
 
+
 
” bits”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/HopcroftKarp.java
edu/princeton/cs/algs4/HopcroftKarp.java
/******************************************************************************

 *  Compilation:  javac HopcroftKarp.java

 *  Execution:    java HopcroftKarp V1 V2 E

 *  Dependencies: FordFulkerson.java FlowNetwork.java FlowEdge.java

 *                BipartiteX.java

 *

 *  Find a maximum cardinality matching (and minimum cardinality vertex cover)

 *  in a bipartite graph using Hopcroft-Karp algorithm.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

/**

 *  The {
@code
 HopcroftKarp} class represents a data type for computing a

 *  maximum (cardinality) matching and a

 *  minimum (cardinality) vertex cover in a bipartite graph.

 *  A bipartite graph in a graph whose vertices can be partitioned

 *  into two disjoint sets such that every edge has one endpoint in either set.

 *  A matching in a graph is a subset of its edges with no common

 *  vertices. A maximum matching is a matching with the maximum number

 *  of edges.

 *  A perfect matching is a matching which matches all vertices in the graph.

 *  A vertex cover in a graph is a subset of its vertices such that

 *  every edge is incident to at least one vertex. A minimum vertex cover

 *  is a vertex cover with the minimum number of vertices.

 *  By Konig’s theorem, in any biparite

 *  graph, the maximum number of edges in matching equals the minimum number

 *  of vertices in a vertex cover.

 *  The maximum matching problem in nonbipartite graphs is

 *  also important, but all known algorithms for this more general problem

 *  are substantially more complicated.

 *  

 *  This implementation uses the Hopcroft-Karp algorithm.

 *  The order of growth of the running time in the worst case is

 *  (E + V) sqrt(V),

 *  where E is the number of edges and V is the number

 *  of vertices in the graph. It uses extra space (not including the graph)

 *  proportional to V.

 *  

 *  See also {
@link
 BipartiteMatching}, which solves the problem in

 *  O(E V) time using the alternating path algorithm

 *  and BipartiteMatchingToMaxflow,

 *  which solves the problem in O(E V) time via a reduction

 *  to the maxflow problem.

 *  

 *  For additional documentation, see

 *  Section 6.5

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
HopcroftKarp
 
{

    
private
 
static
 
final
 
int
 UNMATCHED 
=
 

1
;

    
private
 
final
 
int
 V
;
                 
// number of vertices in the graph

    
private
 
BipartiteX
 bipartition
;
      
// the bipartition

    
private
 
int
 cardinality
;
             
// cardinality of current matching

    
private
 
int
[]
 mate
;
                  
// mate[v] =  w if v-w is an edge in current matching

                                         
//         = -1 if v is not in current matching

    
private
 
boolean
[]
 inMinVertexCover
;
  
// inMinVertexCover[v] = true iff v is in min vertex cover

    
private
 
boolean
[]
 marked
;
            
// marked[v] = true iff v is reachable via alternating path

    
private
 
int
[]
 distTo
;
                
// distTo[v] = number of edges on shortest path to v

    
/**

     * Determines a maximum matching (and a minimum vertex cover)

     * in a bipartite graph.

     *

     * 
@param
  G the bipartite graph

     * 
@throws
 IllegalArgumentException if {
@code
 G} is not bipartite

     */

    
public
 
HopcroftKarp
(
Graph
 G
)
 
{

        bipartition 
=
 
new
 
BipartiteX
(
G
);

        
if
 
(
!
bipartition
.
isBipartite
())
 
{

            
throw
 
new
 
IllegalArgumentException
(
“graph is not bipartite”
);

        
}

        
// initialize empty matching

        
this
.

=
 G
.
V
();

        mate 
=
 
new
 
int
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             mate [ v ]   =  UNMATCHED ;          // the call to hasAugmentingPath() provides enough info to reconstruct level graph          while   ( hasAugmentingPath ( G ))   {              // to be able to iterate over each adjacency list, keeping track of which              // vertex in each adjacency list needs to be explored next              Iterator < Integer >
[]
 adj 
=
 
(
Iterator
< Integer >
[])
 
new
 
Iterator
[
G
.
V
()];

            
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )                 adj [ v ]   =  G . adj ( v ). iterator ();              // for each unmatched vertex s on one side of bipartition              for   ( int  s  =   0 ;  s  <  V ;  s ++ )   {                  if   ( isMatched ( s )   ||   ! bipartition . color ( s ))   continue ;     // or use distTo[s] == 0                  // find augmenting path from s using nonrecursive DFS                  Stack < Integer >
 path 
=
 
new
 
Stack
< Integer >
();

                path
.
push
(
s
);

                
while
 
(
!
path
.
isEmpty
())
 
{

                    
int
 v 
=
 path
.
peek
();

                    
// retreat, no more edges in level graph leaving v

                    
if
 
(
!
adj
[
v
].
hasNext
())

                        path
.
pop
();

                    
// advance

                    
else
 
{

                        
// process edge v-w only if it is an edge in level graph

                        
int
 w 
=
 adj
[
v
].
next
();

                        
if
 
(
!
isLevelGraphEdge
(
v
,
 w
))
 
continue
;

                        
// add w to augmenting path

                        path
.
push
(
w
);

                        
// augmenting path found: update the matching

                        
if
 
(
!
isMatched
(
w
))
 
{

                            
// StdOut.println(“augmenting path: ” + toString(path));

                            
while
 
(
!
path
.
isEmpty
())
 
{

                                
int
 x 
=
 path
.
pop
();

                                
int
 y 
=
 path
.
pop
();

                                mate
[
x
]
 
=
 y
;

                                mate
[
y
]
 
=
 x
;

                            
}

                            cardinality
++
;

                        
}

                    
}

                
}

            
}

        
}

        
// also find a min vertex cover

        inMinVertexCover 
=
 
new
 
boolean
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( bipartition . color ( v )   &&   ! marked [ v ])  inMinVertexCover [ v ]   =   true ;              if   ( ! bipartition . color ( v )   &&  marked [ v ])  inMinVertexCover [ v ]   =   true ;          }          assert  certifySolution ( G );      }      // string representation of augmenting path (chop off last vertex)      private   static   String  toString ( Iterable < Integer >
 path
)
 
{

        
StringBuilder
 sb 
=
 
new
 
StringBuilder
();

        
for
 
(
int
 v 
:
 path
)

            sb
.
append
(

+
 
“-”
);

        
String
 s 
=
 sb
.
toString
();

        s 
=
 s
.
substring
(
0
,
 s
.
lastIndexOf
(
‘-‘
));

        
return
 s
;

    
}

   
// is the edge v-w in the level graph?

    
private
 
boolean
 isLevelGraphEdge
(
int
 v
,
 
int
 w
)
 
{

        
return
 
(
distTo
[
w
]
 
==
 distTo
[
v
]
 
+
 
1
)
 
&&
 isResidualGraphEdge
(
v
,
 w
);

    
}

   
// is the edge v-w a forward edge not in the matching or a reverse edge in the matching?

    
private
 
boolean
 isResidualGraphEdge
(
int
 v
,
 
int
 w
)
 
{

        
if
 
((
mate
[
v
]
 
!=
 w
)
 
&&
  bipartition
.
color
(
v
))
 
return
 
true
;

        
if
 
((
mate
[
v
]
 
==
 w
)
 
&&
 
!
bipartition
.
color
(
v
))
 
return
 
true
;

        
return
 
false
;

    
}

    
/*

     * is there an augmenting path?

     *   – if so, upon termination adj[] contains the level graph;

     *   – if not, upon termination marked[] specifies those vertices reachable via an alternating

     *     path from one side of the bipartition

     *

     * an alternating path is a path whose edges belong alternately to the matching and not

     * to the matching

     *

     * an augmenting path is an alternating path that starts and ends at unmatched vertices

     */

    
private
 
boolean
 hasAugmentingPath
(
Graph
 G
)
 
{

        
// shortest path distances

        marked 
=
 
new
 
boolean
[
V
];

        distTo 
=
 
new
 
int
[
V
];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )             distTo [ v ]   =   Integer . MAX_VALUE ;          // breadth-first search (starting from all unmatched vertices on one side of bipartition)          Queue < Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( bipartition . color ( v )   &&   ! isMatched ( v ))   {                 queue . enqueue ( v );                 marked [ v ]   =   true ;                 distTo [ v ]   =   0 ;              }          }          // run BFS until an augmenting path is found          // (and keep going until all vertices at that distance are explored)          boolean  hasAugmentingPath  =   false ;          while   ( ! queue . isEmpty ())   {              int  v  =  queue . dequeue ();              for   ( int  w  :  G . adj ( v ))   {                  // forward edge not in matching or backwards edge in matching                  if   ( isResidualGraphEdge ( v ,  w ))   {                      if   ( ! marked [ w ])   {                         distTo [ w ]   =  distTo [ v ]   +   1 ;                         marked [ w ]   =   true ;                          if   ( ! isMatched ( w ))                             hasAugmentingPath  =   true ;                          // stop enqueuing vertices once an alternating path has been discovered                          // (no vertex on same side will be marked if its shortest path distance longer)                          if   ( ! hasAugmentingPath )  queue . enqueue ( w );                      }                  }              }          }          return  hasAugmentingPath ;      }      /**      * Returns the vertex to which the specified vertex is matched in      * the maximum matching computed by the algorithm.      *      *  @param   v the vertex      *  @return  the vertex to which vertex { @code  v} is matched in the      *         maximum matching; { @code  -1} if the vertex is not matched      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *      */      public   int  mate ( int  v )   {         validate ( v );          return  mate [ v ];      }      /**      * Returns true if the specified vertex is matched in the maximum matching      * computed by the algorithm.      *      *  @param   v the vertex      *  @return  { @code  true} if vertex { @code  v} is matched in maximum matching;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *      */      public   boolean  isMatched ( int  v )   {         validate ( v );          return  mate [ v ]   !=  UNMATCHED ;      }      /**      * Returns the number of edges in any maximum matching.      *      *  @return  the number of edges in any maximum matching      */      public   int  size ()   {          return  cardinality ;      }      /**      * Returns true if the graph contains a perfect matching.      * That is, the number of edges in a maximum matching is equal to one half      * of the number of vertices in the graph (so that every vertex is matched).      *      *  @return  { @code  true} if the graph contains a perfect matching;      *         { @code  false} otherwise      */      public   boolean  isPerfect ()   {          return  cardinality  *   2   ==  V ;      }      /**      * Returns true if the specified vertex is in the minimum vertex cover      * computed by the algorithm.      *      *  @param   v the vertex      *  @return  { @code  true} if vertex { @code  v} is in the minimum vertex cover;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   boolean  inMinVertexCover ( int  v )   {         validate ( v );          return  inMinVertexCover [ v ];      }      // throw an exception if vertex is invalid      private   void  validate ( int  v )   {          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**************************************************************************

     *   

     *  The code below is solely for testing correctness of the data type.

     *

     **************************************************************************/

    
// check that mate[] and inVertexCover[] define a max matching and min vertex cover, respectively

    
private
 
boolean
 certifySolution
(
Graph
 G
)
 
{

        
// check that mate(v) = w iff mate(w) = v

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( mate ( v )   ==   - 1 )   continue ;              if   ( mate ( mate ( v ))   !=  v )   return   false ;          }          // check that size() is consistent with mate()          int  matchedVertices  =   0 ;          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              if   ( mate ( v )   !=   - 1 )  matchedVertices ++ ;          }          if   ( 2 * size ()   !=  matchedVertices )   return   false ;          // check that size() is consistent with minVertexCover()          int  sizeOfMinVertexCover  =   0 ;          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              if   ( inMinVertexCover ( v ))  sizeOfMinVertexCover ++ ;          if   ( size ()   !=  sizeOfMinVertexCover )   return   false ;          // check that mate() uses each vertex at most once          boolean []  isMatched  =   new   boolean [ V ];          for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {              int  w  =  mate [ v ];              if   ( w  ==   - 1 )   continue ;              if   ( v  ==  w )   return   false ;              if   ( v  >=
 w
)
 
continue
;

            
if
 
(
isMatched
[
v
]
 
||
 isMatched
[
w
])
 
return
 
false
;

            isMatched
[
v
]
 
=
 
true
;

            isMatched
[
w
]
 
=
 
true
;

        
}

        
// check that mate() uses only edges that appear in the graph

        
for
 
(
int
 v 
=
 
0
;
 v 
<  V ;  v ++ )   {              if   ( mate ( v )   ==   - 1 )   continue ;              boolean  isEdge  =   false ;              for   ( int  w  :  G . adj ( v ))   {                  if   ( mate ( v )   ==  w )  isEdge  =   true ;              }              if   ( ! isEdge )   return   false ;          }          // check that inMinVertexCover() is a vertex cover          for   ( int  v  =   0 ;  v  <  V ;  v ++ )              for   ( int  w  :  G . adj ( v ))                  if   ( ! inMinVertexCover ( v )   &&   ! inMinVertexCover ( w ))   return   false ;          return   true ;      }      /**       * Unit tests the { @code  HopcroftKarp} data type.         * Takes three command-line arguments { @code  V1}, { @code  V2}, and { @code  E};      * creates a random bipartite graph with { @code  V1} + { @code  V2} vertices      * and { @code  E} edges; computes a maximum matching and minimum vertex cover;      * and prints the results.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  V1  =   Integer . parseInt ( args [ 0 ]);          int  V2  =   Integer . parseInt ( args [ 1 ]);          int  E   =   Integer . parseInt ( args [ 2 ]);          Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );          if   ( G . V ()   <   1000 )   StdOut . println ( G );          HopcroftKarp  matching  =   new   HopcroftKarp ( G );          // print maximum matching          StdOut . printf ( "Number of edges in max matching        = %d\n" ,  matching . size ());          StdOut . printf ( "Number of vertices in min vertex cover = %d\n" ,  matching . size ());          StdOut . printf ( "Graph has a perfect matching           = %b\n" ,  matching . isPerfect ());          StdOut . println ();          if   ( G . V ()   >=
 
1000
)
 
return
;

        
StdOut
.
print
(
“Max matching: ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              int  w  =  matching . mate ( v );              if   ( matching . isMatched ( v )   &&  v  <  w )    // print each edge only once                  StdOut . print ( v  +   "-"   +  w  +   " " );          }          StdOut . println ();          // print minimum vertex cover          StdOut . print ( "Min vertex cover: " );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )              if   ( matching . inMinVertexCover ( v ))                  StdOut . print ( v  +   " " );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Huffman.java edu/princeton/cs/algs4/Huffman.java /******************************************************************************  *  Compilation:  javac Huffman.java  *  Execution:    java Huffman - < input.txt   (compress)  *  Execution:    java Huffman + < input.txt   (expand)  *  Dependencies: BinaryIn.java BinaryOut.java  *  Data files:   https://algs4.cs.princeton.edu/55compression/abra.txt  *                https://algs4.cs.princeton.edu/55compression/tinytinyTale.txt  *                https://algs4.cs.princeton.edu/55compression/medTale.txt  *                https://algs4.cs.princeton.edu/55compression/tale.txt  *  *  Compress or expand a binary input stream using the Huffman algorithm.  *  *  % java Huffman - < abra.txt | java BinaryDump 60  *  010100000100101000100010010000110100001101010100101010000100  *  000000000000000000000000000110001111100101101000111110010100  *  120 bits  *  *  % java Huffman - < abra.txt | java Huffman +  *  ABRACADABRA!  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Huffman} class provides static methods for compressing  *  and expanding a binary input using Huffman codes over the 8-bit extended  *  ASCII alphabet.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Huffman
 
{

    
// alphabet size of extended ASCII

    
private
 
static
 
final
 
int
 R 
=
 
256
;

    
// Do not instantiate.

    
private
 
Huffman
()
 
{
 
}

    
// Huffman trie node

    
private
 
static
 
class
 
Node
 
implements
 
Comparable
< Node >
 
{

        
private
 
final
 
char
 ch
;

        
private
 
final
 
int
 freq
;

        
private
 
final
 
Node
 left
,
 right
;

        
Node
(
char
 ch
,
 
int
 freq
,
 
Node
 left
,
 
Node
 right
)
 
{

            
this
.
ch    
=
 ch
;

            
this
.
freq  
=
 freq
;

            
this
.
left  
=
 left
;

            
this
.
right 
=
 right
;

        
}

        
// is the node a leaf node?

        
private
 
boolean
 isLeaf
()
 
{

            
assert
 
((
left 
==
 
null
)
 
&&
 
(
right 
==
 
null
))
 
||
 
((
left 
!=
 
null
)
 
&&
 
(
right 
!=
 
null
));

            
return
 
(
left 
==
 
null
)
 
&&
 
(
right 
==
 
null
);

        
}

        
// compare, based on frequency

        
public
 
int
 compareTo
(
Node
 that
)
 
{

            
return
 
this
.
freq 

 that
.
freq
;

        
}

    
}

    
/**

     * Reads a sequence of 8-bit bytes from standard input; compresses them

     * using Huffman codes with an 8-bit alphabet; and writes the results

     * to standard output.

     */

    
public
 
static
 
void
 compress
()
 
{

        
// read the input

        
String
 s 
=
 
BinaryStdIn
.
readString
();

        
char
[]
 input 
=
 s
.
toCharArray
();

        
// tabulate frequency counts

        
int
[]
 freq 
=
 
new
 
int
[
R
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  input . length ;  i ++ )             freq [ input [ i ]] ++ ;          // build Huffman trie          Node  root  =  buildTrie ( freq );          // build code table          String []  st  =   new   String [ R ];         buildCode ( st ,  root ,   "" );          // print trie for decoder         writeTrie ( root );          // print number of bytes in original uncompressed message          BinaryStdOut . write ( input . length );          // use Huffman code to encode input          for   ( int  i  =   0 ;  i  <  input . length ;  i ++ )   {              String  code  =  st [ input [ i ]];              for   ( int  j  =   0 ;  j  <  code . length ();  j ++ )   {                  if   ( code . charAt ( j )   ==   '0' )   {                      BinaryStdOut . write ( false );                  }                  else   if   ( code . charAt ( j )   ==   '1' )   {                      BinaryStdOut . write ( true );                  }                  else   throw   new   IllegalStateException ( "Illegal state" );              }          }          // close output stream          BinaryStdOut . close ();      }      // build the Huffman trie given frequencies      private   static   Node  buildTrie ( int []  freq )   {          // initialze priority queue with singleton trees          MinPQ < Node >
 pq 
=
 
new
 
MinPQ
< Node >
();

        
for
 
(
char
 c 
=
 
0
;
 c 
<  R ;  c ++ )              if   ( freq [ c ]   >
 
0
)

                pq
.
insert
(
new
 
Node
(
c
,
 freq
[
c
],
 
null
,
 
null
));

        
// merge two smallest trees

        
while
 
(
pq
.
size
()
 
>
 
1
)
 
{

            
Node
 left  
=
 pq
.
delMin
();

            
Node
 right 
=
 pq
.
delMin
();

            
Node
 parent 
=
 
new
 
Node
(
‘\0’
,
 left
.
freq 
+
 right
.
freq
,
 left
,
 right
);

            pq
.
insert
(
parent
);

        
}

        
return
 pq
.
delMin
();

    
}

    
// write bitstring-encoded trie to standard output

    
private
 
static
 
void
 writeTrie
(
Node
 x
)
 
{

        
if
 
(
x
.
isLeaf
())
 
{

            
BinaryStdOut
.
write
(
true
);

            
BinaryStdOut
.
write
(
x
.
ch
,
 
8
);

            
return
;

        
}

        
BinaryStdOut
.
write
(
false
);

        writeTrie
(
x
.
left
);

        writeTrie
(
x
.
right
);

    
}

    
// make a lookup table from symbols and their encodings

    
private
 
static
 
void
 buildCode
(
String
[]
 st
,
 
Node
 x
,
 
String
 s
)
 
{

        
if
 
(
!
x
.
isLeaf
())
 
{

            buildCode
(
st
,
 x
.
left
,
  s 
+
 
‘0’
);

            buildCode
(
st
,
 x
.
right
,
 s 
+
 
‘1’
);

        
}

        
else
 
{

            st
[
x
.
ch
]
 
=
 s
;

        
}

    
}

    
/**

     * Reads a sequence of bits that represents a Huffman-compressed message from

     * standard input; expands them; and writes the results to standard output.

     */

    
public
 
static
 
void
 expand
()
 
{

        
// read in Huffman trie from input stream

        
Node
 root 
=
 readTrie
();
 

        
// number of bytes to write

        
int
 length 
=
 
BinaryStdIn
.
readInt
();

        
// decode using the Huffman trie

        
for
 
(
int
 i 
=
 
0
;
 i 
<  length ;  i ++ )   {              Node  x  =  root ;              while   ( ! x . isLeaf ())   {                  boolean  bit  =   BinaryStdIn . readBoolean ();                  if   ( bit )  x  =  x . right ;                  else      x  =  x . left ;              }              BinaryStdOut . write ( x . ch ,   8 );          }          BinaryStdOut . close ();      }      private   static   Node  readTrie ()   {          boolean  isLeaf  =   BinaryStdIn . readBoolean ();          if   ( isLeaf )   {              return   new   Node ( BinaryStdIn . readChar (),   - 1 ,   null ,   null );          }          else   {              return   new   Node ( '\0' ,   - 1 ,  readTrie (),  readTrie ());          }      }      /**      * Sample client that calls { @code  compress()} if the command-line      * argument is "-" an { @code  expand()} if it is "+".      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          if        ( args [ 0 ]. equals ( "-" ))  compress ();          else   if   ( args [ 0 ]. equals ( "+" ))  expand ();          else   throw   new   IllegalArgumentException ( "Illegal command line argument" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/IndexBinomialMinPQ.java edu/princeton/cs/algs4/IndexBinomialMinPQ.java /******************************************************************************  *  Compilation: javac IndexBinomialMinPQ.java  *  Execution:  *    *  An index binomial heap.  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The IndexBinomialMinPQ class represents an indexed priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum operations,  *  along with delete and change-the-key methods.   *  In order to let the client refer to keys on the priority queue,  *  an integer between 0 and N-1 is associated with each key ; the client  *  uses this integer to specify which key to delete or change.  *  It also supports methods for peeking at the minimum key,  *  testing if the priority queue is empty, and iterating through  *  the keys.  *    *  This implementation uses a binomial heap along with an array to associate  *  keys with integers in the given range.  *  The insert, delete-the-minimum, delete, change-key, decrease-key,  *  increase-key and size operations take logarithmic time.  *  The is-empty, min-index, min-key, and key-of operations take constant time.  *  Construction takes time proportional to the specified capacity.  *  *   @author  Tristan Claverie  */ public   class   IndexBinomialMinPQ < Key >
 
implements
 
Iterable
< Integer >
 
{

    
private
 
Node
< Key >
 head
;
             
//Head of the list of roots

    
private
 
Node
< Key >
[]
 nodes
;
          
//Array of indexed Nodes of the heap

    
private
 
int
 n
;
                  
//Maximum size of the tree

    
private
 
final
 
Comparator
< Key >
 comparator
;
   
//Comparator over the keys

    

    
//Represents a node of a Binomial Tree

    
private
 
class
 
Node
< Key >
 
{

        
Key
 key
;
                
//Key contained by the Node

        
int
 order
;
              
//The order of the Binomial Tree rooted by this Node

        
int
 index
;
              
//Index associated with the Key

        
Node
< Key >
 parent
;
           
//parent of this Node

        
Node
< Key >
 child
,
 sibling
;
       
//child and sibling of this Node

    
}

    

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0} to {
@code
 N-1}

     * Worst case is O(n)

     * 
@param
 N number of keys in the priority queue, index from {
@code
 0} to {
@code
 N-1}

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 N < 0}      */      public   IndexBinomialMinPQ ( int  N )   {          if   ( N  <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );         comparator  =   new   MyComparator ();         nodes  =   ( Node < Key >
[])
 
new
 
Node
[
N
];

        
this
.

=
 N
;

    
}

    

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0} to {
@code
 N-1}

     * Worst case is O(n)

     * 
@param
 N number of keys in the priority queue, index from {
@code
 0} to {
@code
 N-1}

     * 
@param
 comparator a Comparator over the keys

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 N < 0}      */      public   IndexBinomialMinPQ ( int  N ,   Comparator < Key >
 comparator
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );          this . comparator  =  comparator ;         nodes  =   ( Node < Key >
[])
 
new
 
Node
[
N
];

        
this
.

=
 N
;

    
}

    
/**

     * Whether the priority queue is empty

     * Worst case is O(1)

     * 
@return
 true if the priority queue is empty, false if not

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 head 
==
 
null
;

    
}

    
/**

     * Does the priority queue contains the index i ?

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@return
 true if i is on the priority queue, false if not

     */

    
public
 
boolean
 contains
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
else
 
return
 nodes
[
i
]
 
!=
 
null
;

    
}

    
/**

     * Number of elements currently on the priority queue

     * Worst case is O(log(n))

     * 
@return
 the number of elements on the priority queue

     */

    
public
 
int
 size
()
 
{

        
int
 result 
=
 
0
,
 tmp
;

        
for
 
(
Node
< Key >
 node 
=
 head
;
 node 
!=
 
null
;
 node 
=
 node
.
sibling
)
 
{

            
if
 
(
node
.
order 
>
 
30
)
 
{
 
throw
 
new
 
ArithmeticException
(
“The number of elements cannot be evaluated, but the priority queue is still valid.”
);
 
}

            tmp 
=
  
1
 
<<  node . order ;             result  |=  tmp ;          }          return  result ;      }      /**      * Associates a key with an index      * Worst case is O(log(n))      *  @param  i an index      *  @param  key a Key associated with i      *  @throws  java.lang.IllegalArgumentException if the specified index is invalid      *  @throws  java.lang.IllegalArgumentException if the index is already in the queue      */      public   void  insert ( int  i ,   Key  key )   {          if   ( i  <   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
contains
(
i
))
 
throw
 
new
 
IllegalArgumentException
(
“Specified index is already in the queue”
);

        
Node
< Key >
 x 
=
 
new
 
Node
< Key >
();

        x
.
key 
=
 key
;

        x
.
index 
=
 i
;

        x
.
order 
=
 
0
;

        nodes
[
i
]
 
=
 x
;

        
IndexBinomialMinPQ
< Key >
 H 
=
 
new
 
IndexBinomialMinPQ
< Key >
();

        H
.
head 
=
 x
;

        head 
=
 union
(
H
).
head
;

    
}

    
/**

     * Gets the index associated with the minimum key

     * Worst case is O(log(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    

    
public
 
int
 minIndex
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
Node
< Key >
 min 
=
 head
;

        
Node
< Key >
 current 
=
 head
;

        
while
 
(
current
.
sibling 
!=
 
null
)
 
{

            min 
=
 
(
greater
(
min
.
key
,
 current
.
sibling
.
key
))
 
?
 current
.
sibling 
:
 min
;

            current 
=
 current
.
sibling
;

        
}

        
return
 min
.
index
;

    
}

    
/**

     * Gets the minimum key currently in the queue

     * Worst case is O(log(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key currently in the priority queue

     */

    

    
public
 
Key
 minKey
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
Node
< Key >
 min 
=
 head
;

        
Node
< Key >
 current 
=
 head
;

        
while
 
(
current
.
sibling 
!=
 
null
)
 
{

            min 
=
 
(
greater
(
min
.
key
,
 current
.
sibling
.
key
))
 
?
 current
.
sibling 
:
 min
;

            current 
=
 current
.
sibling
;

        
}

        
return
 min
.
key
;

    
}

    
/**

     * Deletes the minimum key

     * Worst case is O(log(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    

    
public
 
int
 delMin
()
 
{

        
if
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
Node
< Key >
 min 
=
 eraseMin
();

        
Node
< Key >
 x 
=
 
(
min
.
child 
==
 
null
)
 
?
 min 
:
 min
.
child
;

        
if
 
(
min
.
child 
!=
 
null
)
 
{

            min
.
child 
=
 
null
;

            
Node
< Key >
 prevx 
=
 
null
,
 nextx 
=
 x
.
sibling
;

            
while
 
(
nextx 
!=
 
null
)
 
{

                x
.
parent 
=
 
null
;
 
// for garbage collection

                x
.
sibling 
=
 prevx
;

                prevx 
=
 x
;

                x 
=
 nextx
;
nextx 
=
 nextx
.
sibling
;

            
}

            x
.
parent 
=
 
null
;

            x
.
sibling 
=
 prevx
;

            
IndexBinomialMinPQ
< Key >
 H 
=
 
new
 
IndexBinomialMinPQ
< Key >
();

            H
.
head 
=
 x
;

            head 
=
 union
(
H
).
head
;

        
}

        
return
 min
.
index
;

    
}

    
/**

     * Gets the key associated with index i

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index is not in the queue

     * 
@return
 the key associated with index i

     */

    

    
public
 
Key
 keyOf
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
 
throw
 
new
 
IllegalArgumentException
(
“Specified index is not in the queue”
);

        
return
 nodes
[
i
].
key
;

    
}

    
/**

     * Changes the key associated with index i to the given key

     * Worst case is O(log(n))

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index has no key associated with

     */

    

    
public
 
void
 changeKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
IllegalArgumentException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
nodes
[
i
].
key
,
 key
))
  decreaseKey
(
i
,
 key
);

        
else
                             increaseKey
(
i
,
 key
);

    
}

    
/**

     * Decreases the key associated with index i to the given key

     * Worst case is O(log(n))

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index has no key associated with

     * 
@throws
 java.lang.IllegalArgumentException if the given key is greater than the current key

     */

    

    
public
 
void
 decreaseKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
key
,
 nodes
[
i
].
key
))
  
throw
 
new
 
IllegalArgumentException
(
“Calling with this argument would not decrease the key”
);

        
Node
< Key >
 x 
=
 nodes
[
i
];

        x
.
key 
=
 key
;

        swim
(
i
);

    
}

    
/**

     * Increases the key associated with index i to the given key

     * Worst case is O(log(n))

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index has no key associated with

     * 
@throws
 java.lang.IllegalArgumentException if the given key is lower than the current key

     */

    

    
public
 
void
 increaseKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
nodes
[
i
].
key
,
 key
))
  
throw
 
new
 
IllegalArgumentException
(
“Calling with this argument would not increase the key”
);

        delete
(
i
);

        insert
(
i
,
 key
);

    
}

    
/**

     * Deletes the key associated the given index

     * Worst case is O(log(n))

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the given index has no key associated with

     */

    

    
public
 
void
 delete
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        toTheRoot
(
i
);

        
Node
< Key >
 x 
=
 erase
(
i
);

        
if
 
(
x
.
child 
!=
 
null
)
 
{

            
Node
< Key >
 y 
=
 x
;

            x 
=
 x
.
child
;

            y
.
child 
=
 
null
;

            
Node
< Key >
 prevx 
=
 
null
,
 nextx 
=
 x
.
sibling
;

            
while
 
(
nextx 
!=
 
null
)
 
{

                x
.
parent 
=
 
null
;

                x
.
sibling 
=
 prevx
;

                prevx 
=
 x
;

                x 
=
 nextx
;
 nextx 
=
 nextx
.
sibling
;

            
}

            x
.
parent 
=
 
null
;

            x
.
sibling 
=
 prevx
;

            
IndexBinomialMinPQ
< Key >
 H 
=
 
new
 
IndexBinomialMinPQ
< Key >
();

            H
.
head 
=
 x
;

            head 
=
 union
(
H
).
head
;

        
}

    
}

    

    
/*************************************************

     * General helper functions

     ************************************************/

    

    
//Compares two keys

    
private
 
boolean
 greater
(
Key
 n
,
 
Key
 m
)
 
{

        
if
 
(

==
 
null
)
 
return
 
false
;

        
if
 
(

==
 
null
)
 
return
 
true
;

        
return
 comparator
.
compare
(
n
,
 m
)
 
>
 
0
;

    
}

    

    
//Exchanges the positions of two nodes

    
private
 
void
 exchange
(
Node
< Key >
 x
,
 
Node
< Key >
 y
)
 
{

        
Key
 tempKey 
=
 x
.
key
;
 x
.
key 
=
 y
.
key
;
 y
.
key 
=
 tempKey
;

        
int
 tempInt 
=
 x
.
index
;
 x
.
index 
=
 y
.
index
;
 y
.
index 
=
 tempInt
;

        nodes
[
x
.
index
]
 
=
 x
;

        nodes
[
y
.
index
]
 
=
 y
;

    
}

    

    
//Assuming root1 holds a greater key than root2, root2 becomes the new root

    
private
 
void
 link
(
Node
< Key >
 root1
,
 
Node
< Key >
 root2
)
 
{

        root1
.
sibling 
=
 root2
.
child
;

        root1
.
parent 
=
 root2
;

        root2
.
child 
=
 root1
;

        root2
.
order
++
;

    
}

    

    
/*************************************************

     * Functions for moving upward

     ************************************************/

    

    
//Moves a Node upward

    
private
 
void
 swim
(
int
 i
)
 
{

        
Node
< Key >
 x 
=
 nodes
[
i
];

        
Node
< Key >
 parent 
=
 x
.
parent
;

        
if
 
(
parent 
!=
 
null
 
&&
 greater
(
parent
.
key
,
 x
.
key
))
 
{

            exchange
(
x
,
 parent
);

            swim
(
i
);

        
}

    
}

    

    
//The key associated with i becomes the root of its Binomial Tree,

    
//regardless of the order relation defined for the keys

    
private
 
void
 toTheRoot
(
int
 i
)
 
{

        
Node
< Key >
 x 
=
 nodes
[
i
];

        
Node
< Key >
 parent 
=
 x
.
parent
;

        
if
 
(
parent 
!=
 
null
)
 
{

            exchange
(
x
,
 parent
);

            toTheRoot
(
i
);

        
}

    
}

    

    
/**************************************************

     * Functions for deleting a key

     *************************************************/

    

    
//Assuming the key associated with i is in the root list,

    
//deletes and return the node of index i

    
private
 
Node
< Key >
 erase
(
int
 i
)
 
{

        
Node
< Key >
 reference 
=
 nodes
[
i
];

        
Node
< Key >
 x 
=
 head
;

        
Node
< Key >
 previous 
=
 
null
;

        
while
 
(

!=
 reference
)
 
{

            previous 
=
 x
;

            x 
=
 x
.
sibling
;

        
}

        previous
.
sibling 
=
 x
.
sibling
;

        
if
 
(

==
 head
)
 head 
=
 head
.
sibling
;

        nodes
[
i
]
 
=
 
null
;

        
return
 x
;

    
}

    

    
//Deletes and return the node containing the minimum key

    
private
 
Node
< Key >
 eraseMin
()
 
{

        
Node
< Key >
 min 
=
 head
;

        
Node
< Key >
 previous 
=
 
null
;

        
Node
< Key >
 current 
=
 head
;

        
while
 
(
current
.
sibling 
!=
 
null
)
 
{

            
if
 
(
greater
(
min
.
key
,
 current
.
sibling
.
key
))
 
{

                previous 
=
 current
;

                min 
=
 current
.
sibling
;

            
}

            current 
=
 current
.
sibling
;

        
}

        previous
.
sibling 
=
 min
.
sibling
;

        
if
 
(
min 
==
 head
)
 head 
=
 min
.
sibling
;

        nodes
[
min
.
index
]
 
=
 
null
;

        
return
 min
;

    
}

    

    
/**************************************************

     * Functions for inserting a key in the heap

     *************************************************/

    

    
//Merges two root lists into one, there can be up to 2 Binomial Trees of same order

    
private
 
Node
< Key >
 merge
(
Node
< Key >
 h
,
 
Node
< Key >
 x
,
 
Node
< Key >
 y
)
 
{

        
if
 
(

==
 
null
 
&&
 y 
==
 
null
)
 
return
 h
;

        
else
 
if
 
(

==
 
null
)
         h
.
sibling 
=
 merge
(
y
,
 
null
,
 y
.
sibling
);

        
else
 
if
 
(

==
 
null
)
         h
.
sibling 
=
 merge
(
x
,
 x
.
sibling
,
 
null
);

        
else
 
if
 
(
x
.
order 
<  y . order )  h . sibling  =  merge ( x ,  x . sibling ,  y );          else                         h . sibling  =  merge ( y ,  x ,  y . sibling );          return  h ;      }           //Merges two Binomial Heaps together and returns the resulting Binomial Heap      //It destroys the two Heaps in parameter, which should not be used any after.      //To guarantee logarithmic time, this function assumes the arrays are up-to-date      private   IndexBinomialMinPQ < Key >
 union
(
IndexBinomialMinPQ
< Key >
 heap
)
 
{

        
this
.
head 
=
 merge
(
new
 
Node
< Key >
(),
 
this
.
head
,
 heap
.
head
).
sibling
;

        
Node
< Key >
 x 
=
 
this
.
head
;

        
Node
< Key >
 prevx 
=
 
null
,
 nextx 
=
 x
.
sibling
;

        
while
 
(
nextx 
!=
 
null
)
 
{

            
if
 
(
x
.
order 
<  nextx . order  ||                 ( nextx . sibling  !=   null   &&  nextx . sibling . order  ==  x . order ))   {                 prevx  =  x ;  x  =  nextx ;              }   else   if   ( greater ( nextx . key ,  x . key ))   {                 x . sibling  =  nextx . sibling ;                 link ( nextx ,  x );              }   else   {                  if   ( prevx  ==   null )   {   this . head  =  nextx ;   }                  else   {  prevx . sibling  =  nextx ;   }                 link ( x ,  nextx );                 x  =  nextx ;              }             nextx  =  x . sibling ;          }          return   this ;      }           /******************************************************************      * Constructor      *****************************************************************/           //Creates an empty heap      //The comparator is instanciated because it needs to,      //but won't be used by any heap created by this constructor      private   IndexBinomialMinPQ ()   {  comparator  =   null ;   }           /******************************************************************      * Iterator      *****************************************************************/           /**      * Gets an Iterator over the indexes in the priority queue in ascending order      * The Iterator does not implement the remove() method      * iterator() : Worst case is O(n)      * next() :     Worst case is O(log(n))      * hasNext() :  Worst case is O(1)      *  @return  an Iterator over the indexes in the priority queue in ascending order      */           public   Iterator < Integer >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Integer >
 
{

        
IndexBinomialMinPQ
< Key >
 data
;

        

        
//Constructor clones recursively the elements in the queue

        
//It takes linear time

        
public
 
MyIterator
()
 
{

            data 
=
 
new
 
IndexBinomialMinPQ
< Key >
(
n
,
 comparator
);

            data
.
head 
=
 clone
(
head
,
 
null
);

        
}

        

        
private
 
Node
< Key >
 clone
(
Node
< Key >
 x
,
 
Node
< Key >
 parent
)
 
{

            
if
 
(

==
 
null
)
 
return
 
null
;

            
Node
< Key >
 node 
=
 
new
 
Node
< Key >
();

            node
.
index 
=
 x
.
index
;

            node
.
key 
=
 x
.
key
;

            data
.
nodes
[
node
.
index
]
 
=
 node
;

            node
.
parent 
=
 parent
;

            node
.
sibling 
=
 clone
(
x
.
sibling
,
 parent
);

            node
.
child 
=
 clone
(
x
.
child
,
 node
);

            
return
 node
;

        
}

        

        
public
 
boolean
 hasNext
()
 
{

            
return
 
!
data
.
isEmpty
();

        
}

        

        
public
 
Integer
 next
()
 
{

                        
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
return
 data
.
delMin
();

        
}

        

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

    
}

    

    
/***************************

     * Comparator

     **************************/

    

    
//default Comparator

    
private
 
class
 
MyComparator
 
implements
 
Comparator
< Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

    

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/IndexFibonacciMinPQ.java
edu/princeton/cs/algs4/IndexFibonacciMinPQ.java
/******************************************************************************

 *  Compilation: javac IndexFibonacciMinPQ.java

 *  Execution:

 *  

 *  An index Fibonacci heap.

 *  

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Comparator
;

import
 java
.
util
.
Iterator
;

import
 java
.
util
.
HashMap
;

import
 java
.
util
.
NoSuchElementException
;

/*

 *  The IndexFibonacciMinPQ class represents an indexed priority queue of generic keys.

 *  It supports the usual insert and delete-the-minimum operations,

 *  along with delete and change-the-key methods. 

 *  In order to let the client refer to keys on the priority queue,

 *  an integer between 0 and N-1 is associated with each key ; the client

 *  uses this integer to specify which key to delete or change.

 *  It also supports methods for peeking at the minimum key,

 *  testing if the priority queue is empty, and iterating through

 *  the keys.

 *  

 *  This implementation uses a Fibonacci heap along with an array to associate

 *  keys with integers in the given range.

 *  The insert, size, is-empty, contains, minimum-index, minimum-key

 *  and key-of take constant time.

 *  The decrease-key operation takes amortized constant time.

 *  The delete, increase-key, delete-the-minimum, change-key take amortized logarithmic time.

 *  Construction takes time proportional to the specified capacity

 *

 *  @author Tristan Claverie

 */

public
 
class
 
IndexFibonacciMinPQ
< Key >
 
implements
 
Iterable
< Integer >
 
{

    
private
 
Node
< Key >
[]
 nodes
;
          
//Array of Nodes in the heap

    
private
 
Node
< Key >
 head
;
             
//Head of the circular root list

    
private
 
Node
< Key >
 min
;
              
//Minimum Node in the heap

    
private
 
int
 size
;
                   
//Number of keys in the heap

    
private
 
int
 n
;
                      
//Maximum number of elements in the heap

    
private
 
final
 
Comparator
< Key >
 comp
;
 
//Comparator over the keys

    
private
 
HashMap
< Integer ,   Node < Key >>
 table 
=
 
new
 
HashMap
< Integer ,   Node < Key >>
();
 
//Used for the consolidate operation

    

    
//Represents a Node of a tree

    
private
 
class
 
Node
< Key >
 
{

        
Key
 key
;
                        
//Key of the Node

        
int
 order
;
                      
//The order of the tree rooted by this Node

        
int
 index
;
                      
//Index associated with the key

        
Node
< Key >
 prev
,
 next
;
           
//siblings of the Node

        
Node
< Key >
 parent
,
 child
;
        
//parent and child of this Node

        
boolean
 mark
;
                   
//Indicates if this Node already lost a child

    
}

    

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0} and {
@code
 N-1}

     * Worst case is O(n)

     * 
@param
 N number of keys in the priority queue, index from {
@code
 0} to {
@code
 N-1}

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 N < 0}      */      public   IndexFibonacciMinPQ ( int  N )   {          if   ( N  <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );         n  =  N ;         nodes  =   ( Node < Key >
[])
 
new
 
Node
[
n
];

        comp 
=
 
new
 
MyComparator
();

    
}

    

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0} and {
@code
 N-1}

     * Worst case is O(n)

     * 
@param
 N number of keys in the priority queue, index from {
@code
 0} to {
@code
 N-1}

     * 
@param
 C a Comparator over the keys

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 N < 0}      */      public   IndexFibonacciMinPQ ( Comparator < Key >
 C
,
 
int
 N
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );         n  =  N ;         nodes  =   ( Node < Key >
[])
 
new
 
Node
[
n
];

        comp 
=
 C
;

    
}

    
/**

     * Whether the priority queue is empty

     * Worst case is O(1)

     * 
@return
 true if the priority queue is empty, false if not

     */

    

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size 
==
 
0
;

    
}

    
/**

     * Does the priority queue contains the index i ?

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@return
 true if i is on the priority queue, false if not

     */

    

    
public
 
boolean
 contains
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
else
                 
return
 nodes
[
i
]
 
!=
 
null
;

    
}

    
/**

     * Number of elements currently on the priority queue

     * Worst case is O(1)

     * 
@return
 the number of elements on the priority queue

     */

    

    
public
 
int
 size
()
 
{

        
return
 size
;

    
}

    
/**

     * Associates a key with an index

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@param
 key a Key associated with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index is already in the queue

     */

    

    
public
 
void
 insert
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
contains
(
i
))
 
throw
 
new
 
IllegalArgumentException
(
“Specified index is already in the queue”
);

        
Node
< Key >
 x 
=
 
new
 
Node
< Key >
();

        x
.
key 
=
 key
;

        x
.
index 
=
 i
;

        nodes
[
i
]
 
=
 x
;

        size
++
;

        head 
=
 insert
(
x
,
 head
);

        
if
 
(
min 
==
 
null
)
 min 
=
 head
;

        
else
             min 
=
 
(
greater
(
min
.
key
,
 key
))
 
?
 head 
:
 min
;

    
}

    
/**

     * Get the index associated with the minimum key

     * Worst case is O(1)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    

    
public
 
int
 minIndex
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
return
 min
.
index
;

    
}

    
/**

     * Get the minimum key currently in the queue

     * Worst case is O(1)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key currently in the priority queue

     */

    

    
public
 
Key
 minKey
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
return
 min
.
key
;

    
}

    
/**

     * Delete the minimum key

     * Worst case is O(log(n)) (amortized)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    

    
public
 
int
 delMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        head 
=
 cut
(
min
,
 head
);

        
Node
< Key >
 x 
=
 min
.
child
;

        
int
 index 
=
 min
.
index
;

        min
.
key 
=
 
null
;
                 
//For garbage collection

        
if
 
(

!=
 
null
)
 
{

            
do
 
{

                x
.
parent 
=
 
null
;

                x 
=
 x
.
next
;

            
}
 
while
 
(

!=
 min
.
child
);

            head 
=
 meld
(
head
,
 x
);

            min
.
child 
=
 
null
;
           
//For garbage collection

        
}

        size

;

        
if
 
(
!
isEmpty
())
 consolidate
();

        
else
            min 
=
 
null
;

        nodes
[
index
]
 
=
 
null
;

        
return
 index
;

    
}

    
/**

     * Get the key associated with index i

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index is not in the queue

     * 
@return
 the key associated with index i

     */

    

    
public
 
Key
 keyOf
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
return
 nodes
[
i
].
key
;

    
}

    
/**

     * Changes the key associated with index i to the given key

     * If the given key is greater, Worst case is O(log(n))

     * If the given key is lower, Worst case is O(1) (amortized)

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index has no key associated with

     */

    

    
public
 
void
 changeKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
key
,
 nodes
[
i
].
key
))
  increaseKey
(
i
,
 key
);

        
else
                             decreaseKey
(
i
,
 key
);

    
}

    
/**

     * Decreases the key associated with index i to the given key

     * Worst case is O(1) (amortized).

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index has no key associated with

     * 
@throws
 java.lang.IllegalArgumentException if the given key is greater than the current key

     */

    

    
public
 
void
 decreaseKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
key
,
 nodes
[
i
].
key
))
  
throw
 
new
 
IllegalArgumentException
(
“Calling with this argument would not decrease the key”
);

        
Node
< Key >
 x 
=
 nodes
[
i
];

        x
.
key 
=
 key
;

        
if
 
(
greater
(
min
.
key
,
 key
))
 min 
=
 x
;

        
if
 
(
x
.
parent 
!=
 
null
 
&&
 greater
(
x
.
parent
.
key
,
 key
))
 
{

            cut
(
i
);

        
}

    
}

    
/**

     * Increases the key associated with index i to the given key

     * Worst case is O(log(n))

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the index has no key associated with

     * 
@throws
 java.lang.IllegalArgumentException if the given key is lower than the current key

     */

    

    
public
 
void
 increaseKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
greater
(
nodes
[
i
].
key
,
 key
))
  
throw
 
new
 
IllegalArgumentException
(
“Calling with this argument would not increase the key”
);

        delete
(
i
);

        insert
(
i
,
 key
);

    
}

    
/**

     * Deletes the key associated the given index

     * Worst case is O(log(n)) (amortized)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the given index has no key associated with

     */

    

    
public
 
void
 delete
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 n
)
        
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
contains
(
i
))
           
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
Node
< Key >
 x 
=
 nodes
[
i
];

        x
.
key 
=
 
null
;
               
//For garbage collection

        
if
 
(
x
.
parent 
!=
 
null
)
 
{

            cut
(
i
);

        
}

        head 
=
 cut
(
x
,
 head
);

        
if
 
(
x
.
child 
!=
 
null
)
 
{

            
Node
< Key >
 child 
=
 x
.
child
;

            x
.
child 
=
 
null
;
         
//For garbage collection

            x 
=
 child
;

            
do
 
{

                child
.
parent 
=
 
null
;

                child 
=
 child
.
next
;

            
}
 
while
 
(
child 
!=
 x
);

            head 
=
 meld
(
head
,
 child
);

        
}

        
if
 
(
!
isEmpty
())
 consolidate
();

        
else
            min 
=
 
null
;

        nodes
[
i
]
 
=
 
null
;

        size

;

    
}

    

    
/*************************************

     * General helper functions

     ************************************/

    

    
//Compares two keys

    
private
 
boolean
 greater
(
Key
 n
,
 
Key
 m
)
 
{

        
if
 
(

==
 
null
)
 
return
 
false
;

        
if
 
(

==
 
null
)
 
return
 
true
;

        
return
 comp
.
compare
(
n
,
  m
)
 
>
 
0
;

    
}

    

    
//Assuming root1 holds a greater key than root2, root2 becomes the new root

    
private
 
void
 link
(
Node
< Key >
 root1
,
 
Node
< Key >
 root2
)
 
{

        root1
.
parent 
=
 root2
;

        root2
.
child 
=
 insert
(
root1
,
 root2
.
child
);

        root2
.
order
++
;

    
}

    

    
/*************************************

     * Function for decreasing a key

     ************************************/

    

    
//Removes a Node from its parent’s child list and insert it in the root list

    
//If the parent Node already lost a child, reshapes the heap accordingly

    
private
 
void
 cut
(
int
 i
)
 
{

        
Node
< Key >
 x 
=
 nodes
[
i
];

        
Node
< Key >
 parent 
=
 x
.
parent
;

        parent
.
child 
=
 cut
(
x
,
 parent
.
child
);

        x
.
parent 
=
 
null
;

        parent
.
order

;

        head 
=
 insert
(
x
,
 head
);

        parent
.
mark 
=
 
!
parent
.
mark
;

        
if
 
(
!
parent
.
mark 
&&
 parent
.
parent 
!=
 
null
)
 
{

            cut
(
parent
.
index
);}

    
}

    

    
/*************************************

     * Function for consolidating all trees in the root list

     ************************************/

    

    
//Coalesces the roots, thus reshapes the heap

    
//Caching a HashMap improves greatly performances

    
private
 
void
 consolidate
()
 
{

        table
.
clear
();

        
Node
< Key >
 x 
=
 head
;

        
int
 maxOrder 
=
 
0
;

        min 
=
 head
;

        
Node
< Key >
 y 
=
 
null
,
 z 
=
 
null
;

        
do
 
{

            y 
=
 x
;

            x 
=
 x
.
next
;

            z 
=
 table
.
get
(
y
.
order
);

            
while
 
(

!=
 
null
)
 
{

                table
.
remove
(
y
.
order
);

                
if
 
(
greater
(
y
.
key
,
 z
.
key
))
 
{

                    link
(
y
,
 z
);

                    y 
=
 z
;

                
}
 
else
 
{

                    link
(
z
,
 y
);

                
}

                z 
=
 table
.
get
(
y
.
order
);

            
}

            table
.
put
(
y
.
order
,
 y
);

            
if
 
(
y
.
order 
>
 maxOrder
)
 maxOrder 
=
 y
.
order
;

        
}
 
while
 
(

!=
 head
);

        head 
=
 
null
;

        
for
 
(
Node
< Key >
 n 
:
 table
.
values
())
 
{

            min 
=
 greater
(
min
.
key
,
 n
.
key
)
 
?
 n 
:
 min
;

            head 
=
 insert
(
n
,
 head
);

        
}

    
}

    

    
/*************************************

     * General helper functions for manipulating circular lists

     ************************************/

    

    
//Inserts a Node in a circular list containing head, returns a new head

    
private
 
Node
< Key >
 insert
(
Node
< Key >
 x
,
 
Node
< Key >
 head
)
 
{

        
if
 
(
head 
==
 
null
)
 
{

            x
.
prev 
=
 x
;

            x
.
next 
=
 x
;

        
}
 
else
 
{

            head
.
prev
.
next 
=
 x
;

            x
.
next 
=
 head
;

            x
.
prev 
=
 head
.
prev
;

            head
.
prev 
=
 x
;

        
}

        
return
 x
;

    
}

    

    
//Removes a tree from the list defined by the head pointer

    
private
 
Node
< Key >
 cut
(
Node
< Key >
 x
,
 
Node
< Key >
 head
)
 
{

        
if
 
(
x
.
next 
==
 x
)
 
{

            x
.
next 
=
 
null
;

            x
.
prev 
=
 
null
;

            
return
 
null
;

        
}
 
else
 
{

            x
.
next
.
prev 
=
 x
.
prev
;

            x
.
prev
.
next 
=
 x
.
next
;

            
Node
< Key >
 res 
=
 x
.
next
;

            x
.
next 
=
 
null
;

            x
.
prev 
=
 
null
;

            
if
 
(
head 
==
 x
)
  
return
 res
;

            
else
            
return
 head
;

        
}

    
}

    

    
//Merges two lists together.

    
private
 
Node
< Key >
 meld
(
Node
< Key >
 x
,
 
Node
< Key >
 y
)
 
{

        
if
 
(

==
 
null
)
 
return
 y
;

        
if
 
(

==
 
null
)
 
return
 x
;

        x
.
prev
.
next 
=
 y
.
next
;

        y
.
next
.
prev 
=
 x
.
prev
;

        x
.
prev 
=
 y
;

        y
.
next 
=
 x
;

        
return
 x
;

    
}

    

    
/*************************************

     * Iterator

     ************************************/

    

    
/**

     * Get an Iterator over the indexes in the priority queue in ascending order

     * The Iterator does not implement the remove() method

     * iterator() : Worst case is O(n)

     * next() :     Worst case is O(log(n)) (amortized)

     * hasNext() :  Worst case is O(1)

     * 
@return
 an Iterator over the indexes in the priority queue in ascending order

     */

    

    
public
 
Iterator
< Integer >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Integer >
 
{

        
private
 
IndexFibonacciMinPQ
< Key >
 copy
;

        

        

        
//Constructor takes linear time

        
public
 
MyIterator
()
 
{

            copy 
=
 
new
 
IndexFibonacciMinPQ
< Key >
(
comp
,
 n
);

            
for
 
(
Node
< Key >
 x 
:
 nodes
)
 
{

                
if
 
(

!=
 
null
)
 copy
.
insert
(
x
.
index
,
 x
.
key
);

            
}

        
}

        

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

        

        
public
 
boolean
 hasNext
()
 
{

            
return
 
!
copy
.
isEmpty
();

        
}

        

        
//Takes amortized logarithmic time

        
public
 
Integer
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
return
 copy
.
delMin
();

        
}

    
}

    

    
/***************************

     * Comparator

     **************************/

    

    
//default Comparator

    
private
 
class
 
MyComparator
 
implements
 
Comparator
< Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

    

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/IndexMaxPQ.java
edu/princeton/cs/algs4/IndexMaxPQ.java
/******************************************************************************

 *  Compilation:  javac IndexMaxPQ.java

 *  Execution:    java IndexMaxPQ

 *  Dependencies: StdOut.java

 *

 *  Maximum-oriented indexed PQ implementation using a binary heap.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

import
 java
.
util
.
NoSuchElementException
;

/**

 *  The {
@code
 IndexMaxPQ} class represents an indexed priority queue of generic keys.

 *  It supports the usual insert and delete-the-maximum

 *  operations, along with delete and change-the-key 

 *  methods. In order to let the client refer to items on the priority queue,

 *  an integer between {
@code
 0} and {
@code
 maxN – 1}

 *  is associated with each key—the client

 *  uses this integer to specify which key to delete or change.

 *  It also supports methods for peeking at a maximum key,

 *  testing if the priority queue is empty, and iterating through

 *  the keys.

 *  

 *  This implementation uses a binary heap along with an

 *  array to associate keys with integers in the given range.

 *  The insertdelete-the-maximumdelete,

 *  change-keydecrease-key, and increase-key

 *  operations take Θ(log n) time in the worst case,

 *  where n is the number of elements in the priority queue.

 *  Construction takes time proportional to the specified capacity.

 *  

 *  For additional documentation, see

 *  Section 2.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of key on this priority queue

 */

public
 
class
 
IndexMaxPQ
< Key   extends   Comparable < Key >>
 
implements
 
Iterable
< Integer >
 
{

    
private
 
int
 maxN
;
        
// maximum number of elements on PQ

    
private
 
int
 n
;
           
// number of elements on PQ

    
private
 
int
[]
 pq
;
        
// binary heap using 1-based indexing

    
private
 
int
[]
 qp
;
        
// inverse of pq – qp[pq[i]] = pq[qp[i]] = i

    
private
 
Key
[]
 keys
;
      
// keys[i] = priority of i

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0}

     * and {
@code
 maxN – 1}.

     *

     * 
@param
  maxN the keys on this priority queue are index from {
@code
 0} to {
@code
 maxN – 1}

     * 
@throws
 IllegalArgumentException if {
@code
 maxN < 0}      */      public   IndexMaxPQ ( int  maxN )   {          if   ( maxN  <   0 )   throw   new   IllegalArgumentException ();          this . maxN  =  maxN ;         n  =   0 ;         keys  =   ( Key [])   new   Comparable [ maxN  +   1 ];      // make this of length maxN??         pq    =   new   int [ maxN  +   1 ];         qp    =   new   int [ maxN  +   1 ];                     // make this of length maxN??          for   ( int  i  =   0 ;  i  <=  maxN ;  i ++ )             qp [ i ]   =   - 1 ;      }      /**      * Returns true if this priority queue is empty.      *      *  @return  { @code  true} if this priority queue is empty;      *         { @code  false} otherwise      */      public   boolean  isEmpty ()   {          return  n  ==   0 ;      }      /**      * Is { @code  i} an index on this priority queue?      *      *  @param   i an index      *  @return  { @code  true} if { @code  i} is an index on this priority queue;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      */      public   boolean  contains ( int  i )   {         validateIndex ( i );          return  qp [ i ]   !=   - 1 ;      }      /**      * Returns the number of keys on this priority queue.      *      *  @return  the number of keys on this priority queue       */      public   int  size ()   {          return  n ;      }     /**      * Associate key with index i.      *      *  @param   i an index      *  @param   key the key to associate with index { @code  i}      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  IllegalArgumentException if there already is an item      *         associated with index { @code  i}      */      public   void  insert ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( contains ( i ))   throw   new   IllegalArgumentException ( "index is already in the priority queue" );         n ++ ;         qp [ i ]   =  n ;         pq [ n ]   =  i ;         keys [ i ]   =  key ;         swim ( n );      }      /**      * Returns an index associated with a maximum key.      *      *  @return  an index associated with a maximum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   int  maxIndex ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          return  pq [ 1 ];      }      /**      * Returns a maximum key.      *      *  @return  a maximum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   Key  maxKey ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          return  keys [ pq [ 1 ]];      }      /**      * Removes a maximum key and returns its associated index.      *      *  @return  an index associated with a maximum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   int  delMax ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          int  max  =  pq [ 1 ];         exch ( 1 ,  n -- );         sink ( 1 );          assert  pq [ n + 1 ]   ==  max ;         qp [ max ]   =   - 1 ;          // delete         keys [ max ]   =   null ;      // to help with garbage collection         pq [ n + 1 ]   =   - 1 ;          // not needed          return  max ;      }      /**      * Returns the key associated with index { @code  i}.      *      *  @param   i the index of the key to return      *  @return  the key associated with index { @code  i}      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   Key  keyOf ( int  i )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          else   return  keys [ i ];      }      /**      * Change the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to change      *  @param   key change the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      */      public   void  changeKey ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );         keys [ i ]   =  key ;         swim ( qp [ i ]);         sink ( qp [ i ]);      }     /**      * Change the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to change      *  @param   key change the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @deprecated  Replaced by { @code  changeKey(int, Key)}.      */     @ Deprecated      public   void  change ( int  i ,   Key  key )   {         validateIndex ( i );         changeKey ( i ,  key );      }      /**      * Increase the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to increase      *  @param   key increase the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  IllegalArgumentException if { @code  key <= keyOf(i)}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   void  increaseKey ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          if   ( keys [ i ]. compareTo ( key )   ==   0 )              throw   new   IllegalArgumentException ( "Calling increaseKey() with a key equal to the key in the priority queue" );          if   ( keys [ i ]. compareTo ( key )   >
 
0
)

            
throw
 
new
 
IllegalArgumentException
(
“Calling increaseKey() with a key that is strictly less than the key in the priority queue”
);

        keys
[
i
]
 
=
 key
;

        swim
(
qp
[
i
]);

    
}

    
/**

     * Decrease the key associated with index {
@code
 i} to the specified value.

     *

     * 
@param
  i the index of the key to decrease

     * 
@param
  key decrease the key associated with index {
@code
 i} to this key

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= i < maxN}      *  @throws  IllegalArgumentException if { @code  key >= keyOf(i)}

     * 
@throws
 NoSuchElementException no key is associated with index {
@code
 i}

     */

    
public
 
void
 decreaseKey
(
int
 i
,
 
Key
 key
)
 
{

        validateIndex
(
i
);

        
if
 
(
!
contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“index is not in the priority queue”
);

        
if
 
(
keys
[
i
].
compareTo
(
key
)
 
==
 
0
)

            
throw
 
new
 
IllegalArgumentException
(
“Calling decreaseKey() with a key equal to the key in the priority queue”
);

        
if
 
(
keys
[
i
].
compareTo
(
key
)
 
<   0 )              throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key that is strictly greater than the key in the priority queue" );         keys [ i ]   =  key ;         sink ( qp [ i ]);      }      /**      * Remove the key on the priority queue associated with index { @code  i}.      *      *  @param   i the index of the key to remove      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   void  delete ( int  i )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          int  index  =  qp [ i ];         exch ( index ,  n -- );         swim ( index );         sink ( index );         keys [ i ]   =   null ;         qp [ i ]   =   - 1 ;      }      // throw an IllegalArgumentException if i is an invalid index      private   void  validateIndex ( int  i )   {          if   ( i  <   0 )   throw   new   IllegalArgumentException ( "index is negative: "   +  i );          if   ( i  >=
 maxN
)
 
throw
 
new
 
IllegalArgumentException
(
“index >= capacity: ”
 
+
 i
);

    
}

   
/***************************************************************************

    * General helper functions.

    ***************************************************************************/

    
private
 
boolean
 less
(
int
 i
,
 
int
 j
)
 
{

        
return
 keys
[
pq
[
i
]].
compareTo
(
keys
[
pq
[
j
]])
 
<   0 ;      }      private   void  exch ( int  i ,   int  j )   {          int  swap  =  pq [ i ];         pq [ i ]   =  pq [ j ];         pq [ j ]   =  swap ;         qp [ pq [ i ]]   =  i ;         qp [ pq [ j ]]   =  j ;      }     /***************************************************************************     * Heap helper functions.     ***************************************************************************/      private   void  swim ( int  k )   {          while   ( k  >
 
1
 
&&
 less
(
k
/
2
,
 k
))
 
{

            exch
(
k
,
 k
/
2
);

            k 
=
 k
/
2
;

        
}

    
}

    
private
 
void
 sink
(
int
 k
)
 
{

        
while
 
(
2
*

<=  n )   {              int  j  =   2 * k ;              if   ( j  <  n  &&  less ( j ,  j + 1 ))  j ++ ;              if   ( ! less ( k ,  j ))   break ;             exch ( k ,  j );             k  =  j ;          }      }      /**      * Returns an iterator that iterates over the keys on the      * priority queue in descending order.      * The iterator doesn't implement { @code  remove()} since it's optional.      *      *  @return  an iterator that iterates over the keys in descending order      */      public   Iterator < Integer >
 iterator
()
 
{

        
return
 
new
 
HeapIterator
();

    
}

    
private
 
class
 
HeapIterator
 
implements
 
Iterator
< Integer >
 
{

        
// create a new pq

        
private
 
IndexMaxPQ
< Key >
 copy
;

        
// add all elements to copy of heap

        
// takes linear time since already in heap order so no keys move

        
public
 
HeapIterator
()
 
{

            copy 
=
 
new
 
IndexMaxPQ
< Key >
(
pq
.
length 

 
1
);

            
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )                 copy . insert ( pq [ i ],  keys [ pq [ i ]]);          }          public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Integer  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  copy . delMax ();          }      }      /**      * Unit tests the { @code  IndexMaxPQ} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // insert a bunch of strings          String []  strings  =   {   "it" ,   "was" ,   "the" ,   "best" ,   "of" ,   "times" ,   "it" ,   "was" ,   "the" ,   "worst"   };          IndexMaxPQ < String >
 pq 
=
 
new
 
IndexMaxPQ
< String >
(
strings
.
length
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  strings . length ;  i ++ )   {             pq . insert ( i ,  strings [ i ]);          }          // print each key using the iterator          for   ( int  i  :  pq )   {              StdOut . println ( i  +   " "   +  strings [ i ]);          }          StdOut . println ();          // increase or decrease the key          for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {              if   ( StdRandom . uniform ()   <   0.5 )                 pq . increaseKey ( i ,  strings [ i ]   +  strings [ i ]);              else                 pq . decreaseKey ( i ,  strings [ i ]. substring ( 0 ,   1 ));          }          // delete and print each key          while   ( ! pq . isEmpty ())   {              String  key  =  pq . maxKey ();              int  i  =  pq . delMax ();              StdOut . println ( i  +   " "   +  key );          }          StdOut . println ();          // reinsert the same strings          for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {             pq . insert ( i ,  strings [ i ]);          }          // delete them in random order          int []  perm  =   new   int [ strings . length ];          for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )             perm [ i ]   =  i ;          StdRandom . shuffle ( perm );          for   ( int  i  =   0 ;  i  <  perm . length ;  i ++ )   {              String  key  =  pq . keyOf ( perm [ i ]);             pq . delete ( perm [ i ]);              StdOut . println ( perm [ i ]   +   " "   +  key );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/IndexMinPQ.java edu/princeton/cs/algs4/IndexMinPQ.java /******************************************************************************  *  Compilation:  javac IndexMinPQ.java  *  Execution:    java IndexMinPQ  *  Dependencies: StdOut.java  *  *  Minimum-oriented indexed PQ implementation using a binary heap.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  IndexMinPQ} class represents an indexed priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum

 *  operations, along with delete and change-the-key 

 *  methods. In order to let the client refer to keys on the priority queue,

 *  an integer between {
@code
 0} and {
@code
 maxN – 1}

 *  is associated with each key—the client uses this integer to specify

 *  which key to delete or change.

 *  It also supports methods for peeking at the minimum key,

 *  testing if the priority queue is empty, and iterating through

 *  the keys.

 *  

 *  This implementation uses a binary heap along with an array to associate

 *  keys with integers in the given range.

 *  The insertdelete-the-minimumdelete,

 *  change-keydecrease-key, and increase-key

 *  operations take Θ(log n) time in the worst case,

 *  where n is the number of elements in the priority queue.

 *  Construction takes time proportional to the specified capacity.

 *  

 *  For additional documentation, see

 *  Section 2.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of key on this priority queue

 */

public
 
class
 
IndexMinPQ
< Key   extends   Comparable < Key >>
 
implements
 
Iterable
< Integer >
 
{

    
private
 
int
 maxN
;
        
// maximum number of elements on PQ

    
private
 
int
 n
;
           
// number of elements on PQ

    
private
 
int
[]
 pq
;
        
// binary heap using 1-based indexing

    
private
 
int
[]
 qp
;
        
// inverse of pq – qp[pq[i]] = pq[qp[i]] = i

    
private
 
Key
[]
 keys
;
      
// keys[i] = priority of i

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0}

     * and {
@code
 maxN – 1}.

     * 
@param
  maxN the keys on this priority queue are index from {
@code
 0}

     *         {
@code
 maxN – 1}

     * 
@throws
 IllegalArgumentException if {
@code
 maxN < 0}      */      public   IndexMinPQ ( int  maxN )   {          if   ( maxN  <   0 )   throw   new   IllegalArgumentException ();          this . maxN  =  maxN ;         n  =   0 ;         keys  =   ( Key [])   new   Comparable [ maxN  +   1 ];      // make this of length maxN??         pq    =   new   int [ maxN  +   1 ];         qp    =   new   int [ maxN  +   1 ];                     // make this of length maxN??          for   ( int  i  =   0 ;  i  <=  maxN ;  i ++ )             qp [ i ]   =   - 1 ;      }      /**      * Returns true if this priority queue is empty.      *      *  @return  { @code  true} if this priority queue is empty;      *         { @code  false} otherwise      */      public   boolean  isEmpty ()   {          return  n  ==   0 ;      }      /**      * Is { @code  i} an index on this priority queue?      *      *  @param   i an index      *  @return  { @code  true} if { @code  i} is an index on this priority queue;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      */      public   boolean  contains ( int  i )   {         validateIndex ( i );          return  qp [ i ]   !=   - 1 ;      }      /**      * Returns the number of keys on this priority queue.      *      *  @return  the number of keys on this priority queue      */      public   int  size ()   {          return  n ;      }      /**      * Associates key with index { @code  i}.      *      *  @param   i an index      *  @param   key the key to associate with index { @code  i}      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  IllegalArgumentException if there already is an item associated      *         with index { @code  i}      */      public   void  insert ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( contains ( i ))   throw   new   IllegalArgumentException ( "index is already in the priority queue" );         n ++ ;         qp [ i ]   =  n ;         pq [ n ]   =  i ;         keys [ i ]   =  key ;         swim ( n );      }      /**      * Returns an index associated with a minimum key.      *      *  @return  an index associated with a minimum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   int  minIndex ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          return  pq [ 1 ];      }      /**      * Returns a minimum key.      *      *  @return  a minimum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   Key  minKey ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          return  keys [ pq [ 1 ]];      }      /**      * Removes a minimum key and returns its associated index.      *  @return  an index associated with a minimum key      *  @throws  NoSuchElementException if this priority queue is empty      */      public   int  delMin ()   {          if   ( n  ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );          int  min  =  pq [ 1 ];         exch ( 1 ,  n -- );         sink ( 1 );          assert  min  ==  pq [ n + 1 ];         qp [ min ]   =   - 1 ;          // delete         keys [ min ]   =   null ;      // to help with garbage collection         pq [ n + 1 ]   =   - 1 ;          // not needed          return  min ;      }      /**      * Returns the key associated with index { @code  i}.      *      *  @param   i the index of the key to return      *  @return  the key associated with index { @code  i}      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   Key  keyOf ( int  i )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          else   return  keys [ i ];      }      /**      * Change the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to change      *  @param   key change the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   void  changeKey ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );         keys [ i ]   =  key ;         swim ( qp [ i ]);         sink ( qp [ i ]);      }      /**      * Change the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to change      *  @param   key change the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @deprecated  Replaced by { @code  changeKey(int, Key)}.      */     @ Deprecated      public   void  change ( int  i ,   Key  key )   {         changeKey ( i ,  key );      }      /**      * Decrease the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to decrease      *  @param   key decrease the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  IllegalArgumentException if { @code  key >= keyOf(i)}

     * 
@throws
 NoSuchElementException no key is associated with index {
@code
 i}

     */

    
public
 
void
 decreaseKey
(
int
 i
,
 
Key
 key
)
 
{

        validateIndex
(
i
);

        
if
 
(
!
contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“index is not in the priority queue”
);

        
if
 
(
keys
[
i
].
compareTo
(
key
)
 
==
 
0
)

            
throw
 
new
 
IllegalArgumentException
(
“Calling decreaseKey() with a key equal to the key in the priority queue”
);

        
if
 
(
keys
[
i
].
compareTo
(
key
)
 
<   0 )              throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key strictly greater than the key in the priority queue" );         keys [ i ]   =  key ;         swim ( qp [ i ]);      }      /**      * Increase the key associated with index { @code  i} to the specified value.      *      *  @param   i the index of the key to increase      *  @param   key increase the key associated with index { @code  i} to this key      *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}      *  @throws  IllegalArgumentException if { @code  key <= keyOf(i)}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   void  increaseKey ( int  i ,   Key  key )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          if   ( keys [ i ]. compareTo ( key )   ==   0 )              throw   new   IllegalArgumentException ( "Calling increaseKey() with a key equal to the key in the priority queue" );          if   ( keys [ i ]. compareTo ( key )   >
 
0
)

            
throw
 
new
 
IllegalArgumentException
(
“Calling increaseKey() with a key strictly less than the key in the priority queue”
);

        keys
[
i
]
 
=
 key
;

        sink
(
qp
[
i
]);

    
}

    
/**

     * Remove the key associated with index {
@code
 i}.

     *

     * 
@param
  i the index of the key to remove

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= i < maxN}      *  @throws  NoSuchElementException no key is associated with index { @code  i}      */      public   void  delete ( int  i )   {         validateIndex ( i );          if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );          int  index  =  qp [ i ];         exch ( index ,  n -- );         swim ( index );         sink ( index );         keys [ i ]   =   null ;         qp [ i ]   =   - 1 ;      }      // throw an IllegalArgumentException if i is an invalid index      private   void  validateIndex ( int  i )   {          if   ( i  <   0 )   throw   new   IllegalArgumentException ( "index is negative: "   +  i );          if   ( i  >=
 maxN
)
 
throw
 
new
 
IllegalArgumentException
(
“index >= capacity: ”
 
+
 i
);

    
}

   
/***************************************************************************

    * General helper functions.

    ***************************************************************************/

    
private
 
boolean
 greater
(
int
 i
,
 
int
 j
)
 
{

        
return
 keys
[
pq
[
i
]].
compareTo
(
keys
[
pq
[
j
]])
 
>
 
0
;

    
}

    
private
 
void
 exch
(
int
 i
,
 
int
 j
)
 
{

        
int
 swap 
=
 pq
[
i
];

        pq
[
i
]
 
=
 pq
[
j
];

        pq
[
j
]
 
=
 swap
;

        qp
[
pq
[
i
]]
 
=
 i
;

        qp
[
pq
[
j
]]
 
=
 j
;

    
}

   
/***************************************************************************

    * Heap helper functions.

    ***************************************************************************/

    
private
 
void
 swim
(
int
 k
)
 
{

        
while
 
(

>
 
1
 
&&
 greater
(
k
/
2
,
 k
))
 
{

            exch
(
k
,
 k
/
2
);

            k 
=
 k
/
2
;

        
}

    
}

    
private
 
void
 sink
(
int
 k
)
 
{

        
while
 
(
2
*

<=  n )   {              int  j  =   2 * k ;              if   ( j  <  n  &&  greater ( j ,  j + 1 ))  j ++ ;              if   ( ! greater ( k ,  j ))   break ;             exch ( k ,  j );             k  =  j ;          }      }     /***************************************************************************     * Iterators.     ***************************************************************************/      /**      * Returns an iterator that iterates over the keys on the      * priority queue in ascending order.      * The iterator doesn't implement { @code  remove()} since it's optional.      *      *  @return  an iterator that iterates over the keys in ascending order      */      public   Iterator < Integer >
 iterator
()
 
{
 
return
 
new
 
HeapIterator
();
 
}

    
private
 
class
 
HeapIterator
 
implements
 
Iterator
< Integer >
 
{

        
// create a new pq

        
private
 
IndexMinPQ
< Key >
 copy
;

        
// add all elements to copy of heap

        
// takes linear time since already in heap order so no keys move

        
public
 
HeapIterator
()
 
{

            copy 
=
 
new
 
IndexMinPQ
< Key >
(
pq
.
length 

 
1
);

            
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )                 copy . insert ( pq [ i ],  keys [ pq [ i ]]);          }          public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Integer  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  copy . delMin ();          }      }      /**      * Unit tests the { @code  IndexMinPQ} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // insert a bunch of strings          String []  strings  =   {   "it" ,   "was" ,   "the" ,   "best" ,   "of" ,   "times" ,   "it" ,   "was" ,   "the" ,   "worst"   };          IndexMinPQ < String >
 pq 
=
 
new
 
IndexMinPQ
< String >
(
strings
.
length
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  strings . length ;  i ++ )   {             pq . insert ( i ,  strings [ i ]);          }          // delete and print each key          while   ( ! pq . isEmpty ())   {              int  i  =  pq . delMin ();              StdOut . println ( i  +   " "   +  strings [ i ]);          }          StdOut . println ();          // reinsert the same strings          for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {             pq . insert ( i ,  strings [ i ]);          }          // print each key using the iterator          for   ( int  i  :  pq )   {              StdOut . println ( i  +   " "   +  strings [ i ]);          }          while   ( ! pq . isEmpty ())   {             pq . delMin ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/IndexMultiwayMinPQ.java edu/princeton/cs/algs4/IndexMultiwayMinPQ.java /******************************************************************************  *  Compilation: javac IndexMultiwayMinPQ.java  *  Execution:  *  *  An inde  multiway heap.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The IndexMultiwayMinPQ class represents an indexed priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum operations,  *  along with delete and change-the-key methods.   *  In order to let the client refer to keys on the priority queue,  *  an integer between 0 and N-1 is associated with each key ; the client  *  uses this integer to specify which key to delete or change.  *  It also supports methods for peeking at the minimum key,  *  testing if the priority queue is empty, and iterating through  *  the keys.  *    *  This implementation uses a multiway heap along with an array to associate  *  keys with integers in the given range.  *  For simplified notations, logarithm in base d will be referred as log-d  *  The delete-the-minimum, delete, change-key and increase-key operations  *  take time proportional to d*log-d(n)  *  The insert and decrease-key take time proportional to log-d(n)  *  The is-empty, min-index, min-key, size, contains and key-of operations take constant time.  *  Construction takes time proportional to the specified capacity.  *    *  The arrays used in this structure have the first d indices empty,  *  it apparently helps with caching effects.  *  *   @author  Tristan Claverie  */ public   class   IndexMultiwayMinPQ < Key >
 
implements
 
Iterable
< Integer >
 
{

    
private
 
final
 
int
 d
;
                
//Dimension of the heap

    
private
 
int
 n
;
                      
//Number of keys currently in the queue

    
private
 
int
 nmax
;
                   
//Maximum number of items in the queue

    
private
 
int
[]
 pq
;
                   
//Multiway heap

    
private
 
int
[]
 qp
;
                   
//Inverse of pq : qp[pq[i]] = pq[qp[i]] = i

    
private
 
Key
[]
 keys
;
                 
//keys[i] = priority of i

    
private
 
final
 
Comparator
< Key >
 comp
;
 
//Comparator over the keys

    

    

    
/**

     * Initializes an empty indexed priority queue with indices between {
@code
 0} to {
@code
 N-1}

     * Worst case is O(n)

     * 
@param
 N number of keys in the priority queue, index from {
@code
 0} to {
@code
 N-1}

     * 
@param
 D dimension of the heap

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 N < 0}      *  @throws  java.lang.IllegalArgumentException if { @code  D < 2}      */      public   IndexMultiwayMinPQ ( int  N ,   int  D )   {          if   ( N  <   0 )   throw   new   IllegalArgumentException ( "Maximum number of elements cannot be negative" );          if   ( D  <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  D ;         nmax  =  N ;         pq  =   new   int [ nmax + D ];         qp  =   new   int [ nmax + D ];         keys  =   ( Key [])   new   Comparable [ nmax + D ];          for   ( int  i  =   0 ;  i  <  nmax + D ;  qp [ i ++ ]   =   - 1 );         comp  =   new   MyComparator ();      }           /**      * Initializes an empty indexed priority queue with indices between { @code  0} to { @code  N-1}      * Worst case is O(n)      *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}      *  @param  D dimension of the heap      *  @param  C a Comparator over the keys      *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}      *  @throws  java.lang.IllegalArgumentException if { @code  D < 2}      */      public   IndexMultiwayMinPQ ( int  N ,   Comparator < Key >
 C
,
 
int
 D
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "Maximum number of elements cannot be negative" );          if   ( D  <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  D ;         nmax  =  N ;         pq  =   new   int [ nmax + D ];         qp  =   new   int [ nmax + D ];         keys  =   ( Key [])   new   Comparable [ nmax + D ];          for   ( int  i  =   0 ;  i  <  nmax + D ;  qp [ i ++ ]   =   - 1 );         comp  =  C ;      }      /**      * Whether the priority queue is empty      * Worst case is O(1)      *  @return  true if the priority queue is empty, false if not      */      public   boolean  isEmpty ()   {          return  n  ==   0 ;      }      /**      * Does the priority queue contains the index i ?      * Worst case is O(1)      *  @param  i an index      *  @throws  java.lang.IllegalArgumentException if the specified index is invalid      *  @return  true if i is on the priority queue, false if not      */      public   boolean  contains ( int  i )   {          if   ( i  <   0   || i  >=
 nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 qp
[
i
+
d
]
 
!=
 

1
;

    
}

    
/**

     * Number of elements currently on the priority queue

     * Worst case is O(1)

     * 
@return
 the number of elements on the priority queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Associates a key with an index

     * Worst case is O(log-d(n))

     * 
@param
 i an index

     * 
@param
 key a Key associated with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index is already in the queue

     */

    
public
 
void
 insert
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
contains
(
i
))
 
throw
 
new
 
IllegalArgumentException
(
“Index already there”
);

        keys
[
i
+
d
]
 
=
 key
;

        pq
[
n
+
d
]
 
=
 i
;

        qp
[
i
+
d
]
 
=
 n
;

        swim
(
n
++
);

    
}

    
/**

     * Gets the index associated with the minimum key

     * Worst case is O(1)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    
public
 
int
 minIndex
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
return
 pq
[
d
];

    
}

    
/**

     * Gets the minimum key currently in the queue

     * Worst case is O(1)

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the minimum key currently in the priority queue

     */

    
public
 
Key
 minKey
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
return
 keys
[
pq
[
d
]
+
d
];

    
}

    
/**

     * Deletes the minimum key

     * Worst case is O(d*log-d(n))

     * 
@throws
 java.util.NoSuchElementException if the priority queue is empty

     * 
@return
 the index associated with the minimum key

     */

    
public
 
int
 delMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue is empty”
);

        
int
 min 
=
 pq
[
d
];

        exch
(
0
,
 

n
);

        sink
(
0
);

        qp
[
min
+
d
]
 
=
 

1
;

        keys
[
pq
[
n
+
d
]
+
d
]
 
=
 
null
;

        pq
[
n
+
d
]
 
=
 

1
;

        
return
 min
;

    
}

    
/**

     * Gets the key associated with index i

     * Worst case is O(1)

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index is not in the queue

     * 
@return
 the key associated with index i

     */

    
public
 
Key
 keyOf
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
 contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
return
 keys
[
i
+
d
];

    
}

    
/**

     * Changes the key associated with index i to the given key

     * If the given key is greater, Worst case is O(d*log-d(n))

     * If the given key is lower,   Worst case is O(log-d(n))

     * 
@param
 i an index

     * 
@param
 key the key to associate with i

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.lang.IllegalArgumentException if the index has no key associated with

     */

    
public
 
void
 changeKey
(
int
 i
,
 
Key
 key
)
 
{

        
if
 
(

<   0   ||  i  >=
 nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
 contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
Key
 tmp 
=
 keys
[
i
+
d
];

        keys
[
i
+
d
]
 
=
 key
;

        
if
 
(
comp
.
compare
(
key
,
 tmp
)
 
<=   0 )   {  swim ( qp [ i + d ]);}          else                               {  sink ( qp [ i + d ]);}      }      /**      * Decreases the key associated with index i to the given key      * Worst case is O(log-d(n))      *  @param  i an index      *  @param  key the key to associate with i      *  @throws  java.lang.IllegalArgumentException if the specified index is invalid      *  @throws  java.util.NoSuchElementException if the index has no key associated with      *  @throws  java.lang.IllegalArgumentException if the given key is greater than the current key      */      public   void  decreaseKey ( int  i ,   Key  key )   {          if   ( i  <   0   ||  i  >=
nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
 contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
comp
.
compare
(
keys
[
i
+
d
],
 key
)
 
<=   0 )   throw   new   IllegalArgumentException ( "Calling with this argument would not decrease the Key" );         keys [ i + d ]   =  key ;         swim ( qp [ i + d ]);      }      /**      * Increases the key associated with index i to the given key      * Worst case is O(d*log-d(n))      *  @param  i an index      *  @param  key the key to associate with i      *  @throws  java.lang.IllegalArgumentException if the specified index is invalid      *  @throws  java.util.NoSuchElementException if the index has no key associated with      *  @throws  java.lang.IllegalArgumentException if the given key is lower than the current key      */      public   void  increaseKey ( int  i ,   Key  key )   {          if   ( i  <   0   ||  i  >=
nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
 contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
if
 
(
comp
.
compare
(
keys
[
i
+
d
],
 key
)
 
>=
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“Calling with this argument would not increase the Key”
);

        keys
[
i
+
d
]
 
=
 key
;

        sink
(
qp
[
i
+
d
]);

    
}

    
/**

     * Deletes the key associated to the given index

     * Worst case is O(d*log-d(n))

     * 
@param
 i an index

     * 
@throws
 java.lang.IllegalArgumentException if the specified index is invalid

     * 
@throws
 java.util.NoSuchElementException if the given index has no key associated with

     */

    
public
 
void
 delete
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 nmax
)
 
throw
 
new
 
IllegalArgumentException
();

        
if
 
(
!
 contains
(
i
))
 
throw
 
new
 
NoSuchElementException
(
“Specified index is not in the queue”
);

        
int
 idx 
=
 qp
[
i
+
d
];

        exch
(
idx
,
 

n
);

        swim
(
idx
);

        sink
(
idx
);

        keys
[
i
+
d
]
 
=
 
null
;

        qp
[
i
+
d
]
 
=
 

1
;

    
}

    

    
/***************************

     * General helper functions

     **************************/

    

    
//Compares two keys

    
private
 
boolean
 greater
(
int
 i
,
 
int
 j
)
 
{

        
return
 comp
.
compare
(
keys
[
pq
[
i
+
d
]
+
d
],
 keys
[
pq
[
j
+
d
]
+
d
])
 
>
 
0
;

    
}

    

    
//Exchanges two keys

    
private
 
void
 exch
(
int
 x
,
 
int
 y
)
 
{

        
int
 i 
=
 x
+
d
,
 j 
=
 y
+
d
;

        
int
 swap 
=
 pq
[
i
];

        pq
[
i
]
 
=
 pq
[
j
];

        pq
[
j
]
 
=
 swap
;

        qp
[
pq
[
i
]
+
d
]
 
=
 x
;

        qp
[
pq
[
j
]
+
d
]
 
=
 y
;

    
}

    

    
/***************************

     * Functions for moving upward or downward

     **************************/

    

    
//Moves upward

    
private
 
void
 swim
(
int
 i
)
 
{

        
if
 
(

>
 
0
 
&&
 greater
((
i

1
)
/
d
,
 i
))
 
{

            exch
(
i
,
 
(
i

1
)
/
d
);

            swim
((
i

1
)
/
d
);

        
}

    
}

    

    
//Moves downward

    
private
 
void
 sink
(
int
 i
)
 
{

        
if
 
(
d
*
i
+
1
 
>=
 n
)
 
return
;

        
int
 min 
=
 minChild
(
i
);

        
while
 
(
min 
<  n  &&  greater ( i ,  min ))   {             exch ( i ,  min );             i  =  min ;             min  =  minChild ( i );          }      }           /***************************      * Deletes the minimum child      **************************/           //Return the minimum child of i      private   int  minChild ( int  i )   {          int  loBound  =  d * i + 1 ,  hiBound  =  d * i + d ;          int  min  =  loBound ;          for   ( int  cur  =  loBound ;  cur  <=  hiBound ;  cur ++ )   {              if   ( cur  <  n  &&  greater ( min ,  cur ))  min  =  cur ;          }          return  min ;      }           /***************************      * Iterator      **************************/           /**      * Gets an Iterator over the indexes in the priority queue in ascending order      * The Iterator does not implement the remove() method      * iterator() : Worst case is O(n)      * next() :     Worst case is O(d*log-d(n))      * hasNext() :  Worst case is O(1)      *  @return  an Iterator over the indexes in the priority queue in ascending order      */           public   Iterator < Integer >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
//Constructs an Iterator over the indices in linear time

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Integer >
 
{

        
IndexMultiwayMinPQ
< Key >
 clone
;

        

        
public
 
MyIterator
()
 
{

            clone 
=
 
new
 
IndexMultiwayMinPQ
< Key >
(
nmax
,
 comp
,
 d
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {                 clone . insert ( pq [ i + d ],  keys [ pq [ i + d ] + d ]);              }          }          public   boolean  hasNext ()   {              return   ! clone . isEmpty ();          }                   public   Integer  next ()   {                          if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  clone . delMin ();          }                   public   void  remove ()   {              throw   new   UnsupportedOperationException ();          }      }           /***************************      * Comparator      **************************/           //default Comparator      private   class   MyComparator   implements   Comparator < Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/In.java
edu/princeton/cs/algs4/In.java
/******************************************************************************

 *  Compilation:  javac In.java

 *  Execution:    java In   (basic test — see source for required files)

 *  Dependencies: none

 *

 *  Reads in data of various types from standard input, files, and URLs.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
io
.
BufferedInputStream
;

import
 java
.
io
.
File
;

import
 java
.
io
.
FileInputStream
;

import
 java
.
io
.
IOException
;

import
 java
.
io
.
InputStream
;

import
 java
.
net
.
URL
;

import
 java
.
net
.
Socket
;

// import java.net.HttpURLConnection;

import
 java
.
net
.
URLConnection
;

import
 java
.
util
.
ArrayList
;

import
 java
.
util
.
InputMismatchException
;

import
 java
.
util
.
Locale
;

import
 java
.
util
.
NoSuchElementException
;

import
 java
.
util
.
Scanner
;

import
 java
.
util
.
regex
.
Pattern
;

/**

 *  Input. This class provides methods for reading strings

 *  and numbers from standard input, file input, URLs, and sockets. 

 *  

 *  The Locale used is: language = English, country = US. This is consistent

 *  with the formatting conventions with Java floating-point literals,

 *  command-line arguments (via {
@link
 Double#parseDouble(String)})

 *  and standard output. 

 *  

 *  For additional documentation, see 

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach 

 *  by Robert Sedgewick and Kevin Wayne.

 *  

 *  Like {
@link
 Scanner}, reading a token also consumes preceding Java

 *  whitespace, reading a full line consumes

 *  the following end-of-line delimeter, while reading a character consumes

 *  nothing extra. 

 *  

 *  Whitespace is defined in {
@link
 Character#isWhitespace(char)}. Newlines

 *  consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;

 *  see 

 *  Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n).

 *

 *  
@author
 David Pritchard

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
In
 
{

    

    
///// begin: section (1 of 2) of code duplicated from In to StdIn.

    

    
// assume Unicode UTF-8 encoding

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with System.out.

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// the default token separator; we maintain the invariant that this value 

    
// is held by the scanner’s delimiter between calls

    
private
 
static
 
final
 
Pattern
 WHITESPACE_PATTERN 
=
 
Pattern
.
compile
(
“\\p{javaWhitespace}+”
);

    
// makes whitespace characters significant 

    
private
 
static
 
final
 
Pattern
 EMPTY_PATTERN 
=
 
Pattern
.
compile
(
“”
);

    
// used to read the entire input. source:

    
// http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html

    
private
 
static
 
final
 
Pattern
 EVERYTHING_PATTERN 
=
 
Pattern
.
compile
(
“\\A”
);

    
//// end: section (1 of 2) of code duplicated from In to StdIn.

    
private
 
Scanner
 scanner
;

   
/**

     * Initializes an input stream from standard input.

     */

    
public
 
In
()
 
{

        scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
System
.
in
),
 CHARSET_NAME
);

        scanner
.
useLocale
(
LOCALE
);

    
}

   
/**

     * Initializes an input stream from a socket.

     *

     * 
@param
  socket the socket

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 socket}

     * 
@throws
 IllegalArgumentException if {
@code
 socket} is {
@code
 null}

     */

    
public
 
In
(
Socket
 socket
)
 
{

        
if
 
(
socket 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“socket argument is null”
);

        
try
 
{

            
InputStream
 is 
=
 socket
.
getInputStream
();

            scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 socket
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a URL.

     *

     * 
@param
  url the URL

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 url}

     * 
@throws
 IllegalArgumentException if {
@code
 url} is {
@code
 null}

     */

    
public
 
In
(
URL url
)
 
{

        
if
 
(
url 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“url argument is null”
);

        
try
 
{

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            scanner            
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 url
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a file.

     *

     * 
@param
  file the file

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 file}

     * 
@throws
 IllegalArgumentException if {
@code
 file} is {
@code
 null}

     */

    
public
 
In
(
File
 file
)
 
{

        
if
 
(
file 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“file argument is null”
);

        
try
 
{

            
// for consistency with StdIn, wrap with BufferedInputStream instead of use

            
// file as argument to Scanner

            
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

            scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
fis
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 file
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a filename or web page name.

     *

     * 
@param
  name the filename or web page name

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 name} as

     *         a file or URL

     * 
@throws
 IllegalArgumentException if {
@code
 name} is {
@code
 null}

     */

    
public
 
In
(
String
 name
)
 
{

        
if
 
(
name 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
name
);

            
if
 
(
file
.
exists
())
 
{

                
// for consistency with StdIn, wrap with BufferedInputStream instead of use

                
// file as argument to Scanner

                
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

                scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
fis
),
 CHARSET_NAME
);

                scanner
.
useLocale
(
LOCALE
);

                
return
;

            
}

            
// resource relative to .class file

            URL url 
=
 getClass
().
getResource
(
name
);

            
// resource relative to classloader root

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 getClass
().
getClassLoader
().
getResource
(
name
);

            
}

            
// or URL from web

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 
new
 URL
(
name
);

            
}

            
URLConnection
 site 
=
 url
.
openConnection
();

            
// in order to set User-Agent, replace above line with these two

            
// HttpURLConnection site = (HttpURLConnection) url.openConnection();

            
// site.addRequestProperty(“User-Agent”, “Mozilla/4.76”);

            
InputStream
 is     
=
 site
.
getInputStream
();

            scanner            
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 name
,
 ioe
);

        
}

    
}

    
/**

     * Initializes an input stream from a given {
@link
 Scanner} source; use with 

     * {
@code
 new Scanner(String)} to read from a string.

     * 

     * Note that this does not create a defensive copy, so the

     * scanner will be mutated as you read on. 

     *

     * 
@param
  scanner the scanner

     * 
@throws
 IllegalArgumentException if {
@code
 scanner} is {
@code
 null}

     */

    
public
 
In
(
Scanner
 scanner
)
 
{

        
if
 
(
scanner 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“scanner argument is null”
);

        
this
.
scanner 
=
 scanner
;

    
}

    
/**

     * Returns true if this input stream exists.

     *

     * 
@return
 {
@code
 true} if this input stream exists; {
@code
 false} otherwise

     */

    
public
 
boolean
 exists
()
  
{

        
return
 scanner 
!=
 
null
;

    
}

    

    
////  begin: section (2 of 2) of code duplicated from In to StdIn,

    
////  with all methods changed from “public” to “public static”.

   
/**

     * Returns true if input stream is empty (except possibly whitespace).

     * Use this to know whether the next call to {
@link
 #readString()}, 

     * {
@link
 #readDouble()}, etc will succeed.

     *

     * 
@return
 {
@code
 true} if this input stream is empty (except possibly whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 
!
scanner
.
hasNext
();

    
}

   
/** 

     * Returns true if this input stream has a next line.

     * Use this method to know whether the

     * next call to {
@link
 #readLine()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextChar()}.

     *

     * 
@return
 {
@code
 true} if this input stream has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasNextLine
()
 
{

        
return
 scanner
.
hasNextLine
();

    
}

    
/**

     * Returns true if this input stream has more input (including whitespace).

     * Use this method to know whether the next call to {
@link
 #readChar()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextLine()}.

     * 

     * 
@return
 {
@code
 true} if this input stream has more input (including whitespace);

     *         {
@code
 false} otherwise   

     */

    
public
 
boolean
 hasNextChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
boolean
 result 
=
 scanner
.
hasNext
();

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

        
return
 result
;

    
}

   
/**

     * Reads and returns the next line in this input stream.

     *

     * 
@return
 the next line in this input stream; {
@code
 null} if no such line

     */

    
public
 
String
 readLine
()
 
{

        
String
 line
;

        
try
 
{

            line 
=
 scanner
.
nextLine
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            line 
=
 
null
;

        
}

        
return
 line
;

    
}

    
/**

     * Reads and returns the next character in this input stream.

     *

     * 
@return
 the next {
@code
 char} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     */

    
public
 
char
 readChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
try
 
{

            
String
 ch 
=
 scanner
.
next
();

            
assert
 ch
.
length
()
 
==
 
1
 
:
 
“Internal (Std)In.readChar() error!”

                
+
 
” Please contact the authors.”
;

            scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

            
return
 ch
.
charAt
(
0
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘char’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}
  

   
/**

     * Reads and returns the remainder of this input stream, as a string.

     *

     * 
@return
 the remainder of this input stream, as a string

     */

    
public
 
String
 readAll
()
 
{

        
if
 
(
!
scanner
.
hasNextLine
())

            
return
 
“”
;

        
String
 result 
=
 scanner
.
useDelimiter
(
EVERYTHING_PATTERN
).
next
();

        
// not that important to reset delimeter, since now scanner is empty

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);
 
// but let’s do it anyway

        
return
 result
;

    
}

   
/**

     * Reads the next token from this input stream and returns it as a {
@code
 String}.

     *

     * 
@return
 the next {
@code
 String} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     */

    
public
 
String
 readString
()
 
{

        
try
 
{

            
return
 scanner
.
next
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘String’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 int},

     * and returns the {
@code
 int}.

     *

     * 
@return
 the next {
@code
 int} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as an {
@code
 int}

     */

    
public
 
int
 readInt
()
 
{

        
try
 
{

            
return
 scanner
.
nextInt
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read an ‘int’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read an ‘int’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 double},

     * and returns the {
@code
 double}.

     *

     * 
@return
 the next {
@code
 double} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 double}

     */

    
public
 
double
 readDouble
()
 
{

        
try
 
{

            
return
 scanner
.
nextDouble
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘double’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘double’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 float},

     * and returns the {
@code
 float}.

     *

     * 
@return
 the next {
@code
 float} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 float}

     */

    
public
 
float
 readFloat
()
 
{

        
try
 
{

            
return
 scanner
.
nextFloat
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘float’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘float’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 long},

     * and returns the {
@code
 long}.

     *

     * 
@return
 the next {
@code
 long} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 long}

     */

    
public
 
long
 readLong
()
 
{

        
try
 
{

            
return
 scanner
.
nextLong
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘long’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘long’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 short},

     * and returns the {
@code
 short}.

     *

     * 
@return
 the next {
@code
 short} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 short}

     */

    
public
 
short
 readShort
()
 
{

        
try
 
{

            
return
 scanner
.
nextShort
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘short’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘short’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 byte},

     * and returns the {
@code
 byte}.

     * 

     * To read binary data, use {
@link
 BinaryIn}.

     *

     * 
@return
 the next {
@code
 byte} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 byte}

     */

    
public
 
byte
 readByte
()
 
{

        
try
 
{

            
return
 scanner
.
nextByte
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘byte’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘byte’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads the next token from this input stream, parses it as a {
@code
 boolean}

     * (interpreting either {
@code
 “true”} or {
@code
 “1”} as {
@code
 true},

     * and either {
@code
 “false”} or {
@code
 “0”} as {
@code
 false}).

     *

     * 
@return
 the next {
@code
 boolean} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 boolean}

     */

    
public
 
boolean
 readBoolean
()
 
{

        
try
 
{

            
String
 token 
=
 readString
();

            
if
 
(
“true”
.
equalsIgnoreCase
(
token
))
  
return
 
true
;

            
if
 
(
“false”
.
equalsIgnoreCase
(
token
))
 
return
 
false
;

            
if
 
(
“1”
.
equals
(
token
))
               
return
 
true
;

            
if
 
(
“0”
.
equals
(
token
))
               
return
 
false
;

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘boolean’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘boolean’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads all remaining tokens from this input stream and returns them as

     * an array of strings.

     *

     * 
@return
 all remaining tokens in this input stream, as an array of strings

     */

    
public
 
String
[]
 readAllStrings
()
 
{

        
// we could use readAll.trim().split(), but that’s not consistent

        
// since trim() uses characters 0x00..0x20 as whitespace

        
String
[]
 tokens 
=
 WHITESPACE_PATTERN
.
split
(
readAll
());

        
if
 
(
tokens
.
length 
==
 
0
 
||
 tokens
[
0
].
length
()
 
>
 
0
)

            
return
 tokens
;

        
String
[]
 decapitokens 
=
 
new
 
String
[
tokens
.
length

1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  tokens . length - 1 ;  i ++ )             decapitokens [ i ]   =  tokens [ i + 1 ];          return  decapitokens ;      }      /**      * Reads all remaining lines from this input stream and returns them as      * an array of strings.      *      *  @return  all remaining lines in this input stream, as an array of strings      */      public   String []  readAllLines ()   {          ArrayList < String >
 lines 
=
 
new
 
ArrayList
< String >
();

        
while
 
(
hasNextLine
())
 
{

            lines
.
add
(
readLine
());

        
}

        
return
 lines
.
toArray
(
new
 
String
[
lines
.
size
()]);

    
}

    
/**

     * Reads all remaining tokens from this input stream, parses them as integers,

     * and returns them as an array of integers.

     *

     * 
@return
 all remaining lines in this input stream, as an array of integers

     */

    
public
 
int
[]
 readAllInts
()
 
{

        
String
[]
 fields 
=
 readAllStrings
();

        
int
[]
 vals 
=
 
new
 
int
[
fields
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  fields . length ;  i ++ )             vals [ i ]   =   Integer . parseInt ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from this input stream, parses them as longs,      * and returns them as an array of longs.      *      *  @return  all remaining lines in this input stream, as an array of longs      */      public   long []  readAllLongs ()   {          String []  fields  =  readAllStrings ();          long []  vals  =   new   long [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Long . parseLong ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from this input stream, parses them as doubles,      * and returns them as an array of doubles.      *      *  @return  all remaining lines in this input stream, as an array of doubles      */      public   double []  readAllDoubles ()   {          String []  fields  =  readAllStrings ();          double []  vals  =   new   double [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Double . parseDouble ( fields [ i ]);          return  vals ;      }           ///// end: section (2 of 2) of code duplicated from In to StdIn */     /**      * Closes this input stream.      */      public   void  close ()   {         scanner . close ();         }      /**      * Reads all integers from a file and returns them as      * an array of integers.      *      *  @param       filename the name of the file      *  @return      the integers in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ( String  filename )   {          return   new   In ( filename ). readAllInts ();      }     /**      * Reads all doubles from a file and returns them as      * an array of doubles.      *      *  @param       filename the name of the file      *  @return      the doubles in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ( String  filename )   {          return   new   In ( filename ). readAllDoubles ();      }     /**      * Reads all strings from a file and returns them as      * an array of strings.      *      *  @param       filename the name of the file      *  @return      the strings in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ( String  filename )   {          return   new   In ( filename ). readAllStrings ();      }      /**      * Reads all integers from standard input and returns them      * an array of integers.      *      *  @return      the integers on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ()   {          return   new   In (). readAllInts ();      }     /**      * Reads all doubles from standard input and returns them as      * an array of doubles.      *      *  @return      the doubles on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ()   {          return   new   In (). readAllDoubles ();      }     /**      * Reads all strings from standard input and returns them as      *  an array of strings.      *      *  @return      the strings on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ()   {          return   new   In (). readAllStrings ();      }          /**      * Unit tests the { @code  In} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in ;          String  urlName  =   "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt" ;          // read from a URL          System . out . println ( "readAll() from URL "   +  urlName );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in = new In(urlName);             System.out.println(in.readAll());         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one line at a time from URL        System.out.println("readLine() from URL " + urlName);         System.out.println("---------------------------------------------------------------------------");         try {             in = new In(urlName);             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one string at a time from URL        System.out.println("readString() from URL " + urlName);         System.out.println("---------------------------------------------------------------------------");         try {             in = new In(urlName);             while (!in.isEmpty()) {                 String s = in.readString();                 System.out.println(s);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one line at a time from file in current directory        System.out.println("readLine() from current directory");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("./InTest.txt");             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one line at a time from file using relative path        System.out.println("readLine() from relative path");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("../stdlib/InTest.txt");             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one char at a time        System.out.println("readChar() from file");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("InTest.txt");             while (!in.isEmpty()) {                 char c = in.readChar();                 System.out.print(c);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         System.out.println();         // read one line at a time from absolute OS X / Linux path        System.out.println("readLine() from absolute OS X / Linux path");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("/n/fs/introcs/www/java/stdlib/InTest.txt");             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();         // read one line at a time from absolute Windows path        System.out.println("readLine() from absolute Windows path");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }             System.out.println();         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();     } } /****************************************************************************** *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. * *  This file is part of algs4.jar, which accompanies the textbook * *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. *      http://algs4.cs.princeton.edu * * *  algs4.jar is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  algs4.jar is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with algs4.jar.  If not, see http://www.gnu.org/licenses. ******************************************************************************/ edu/princeton/cs/algs4/InplaceMSD.java edu/princeton/cs/algs4/InplaceMSD.java /******************************************************************************  *  Compilation: javac InplaceMSD.java  *  Execution:   java InplaceMSD < input.txt  *  Dependencies: StdIn.java StdOut.java   *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *                https://algs4.cs.princeton.edu/51radix/shells.txt  *  *  Sort an array of strings or integers using in-place MSD radix sort.  *  *  % java InplaceMSD < shells.txt   *  are  *  by  *  sea  *  seashells  *  seashells  *  sells  *  sells  *  she  *  she  *  shells  *  shore  *  surely  *  the  *  the  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  InplaceMSD} class provides static methods for sorting an  *  array of extended ASCII strings using in-place MSD radix sort.  *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Ivan Pesin

 */

public
 
class
 
InplaceMSD
 
{

    
private
 
static
 
final
 
int
 R             
=
 
256
;
   
// extended ASCII alphabet size

    
private
 
static
 
final
 
int
 CUTOFF        
=
  
15
;
   
// cutoff to insertion sort

    
// do not instantiate

    
private
 
InplaceMSD
()
 
{
 
}
 

   
/**

     * Rearranges the array of extended ASCII strings in ascending order.

     * This is an unstable sorting algorithm.

     *

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
String
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        sort
(
a
,
 
0
,
 n

1
,
 
0
);

    
}

    
// return dth character of s, -1 if d = length of string

    
private
 
static
 
int
 charAt
(
String
 s
,
 
int
 d
)
 
{

        
assert
 d 
>=
 
0
 
&&
 d 
<=  s . length ();          if   ( d  ==  s . length ())   return   - 1 ;          return  s . charAt ( d );      }      // sort from a[lo] to a[hi], starting at the dth character      private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d )   {          // cutoff to insertion sort for small subarrays          if   ( hi  <=  lo  +  CUTOFF )   {             insertion ( a ,  lo ,  hi ,  d );              return ;          }          // compute frequency counts          int []  heads  =   new   int [ R + 2 ];          int []  tails  =   new   int [ R + 1 ];          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              int  c  =  charAt ( a [ i ],  d );             heads [ c + 2 ] ++ ;          }          // transform counts to indices         heads [ 0 ]   =  lo ;          for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )   {             heads [ r + 1 ]   +=  heads [ r ];             tails [ r ]   =  heads [ r + 1 ];          }          // sort by d-th character in-place          for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )   {              while   ( heads [ r ]   <  tails [ r ])   {                  int  c  =  charAt ( a [ heads [ r ]],  d );                  while   ( c  +   1   !=  r )   {                     exch ( a ,  heads [ r ],  heads [ c + 1 ] ++ );                     c  =  charAt ( a [ heads [ r ]],  d );                  }                 heads [ r ] ++ ;              }          }                         // recursively sort for each character (excludes sentinel -1)          for   ( int  r  =   0 ;  r  <  R ;  r ++ )             sort ( a ,  tails [ r ],  tails [ r + 1 ]   -   1 ,  d + 1 );      }      // insertion sort a[lo..hi], starting at dth character      private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
String
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
String
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    
// is v less than w, starting at character d

    
private
 
static
 
boolean
 less
(
String
 v
,
 
String
 w
,
 
int
 d
)
 
{

        
// assert v.substring(0, d).equals(w.substring(0, d));

        
for
 
(
int
 i 
=
 d
;
 i 
<   Math . min ( v . length (),  w . length ());  i ++ )   {              if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;              if   ( v . charAt ( i )   >
 w
.
charAt
(
i
))
 
return
 
false
;

        
}

        
return
 v
.
length
()
 
<  w . length ();      }      /**      * Reads in a sequence of extended ASCII strings from standard input;      * in-place MSD radix sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          int  n  =  a . length ;         sort ( a );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Insertion.java edu/princeton/cs/algs4/Insertion.java /******************************************************************************  *  Compilation:  javac Insertion.java  *  Execution:    java Insertion < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt  *                https://algs4.cs.princeton.edu/21elementary/words3.txt  *    *  Sorts a sequence of strings from standard input using insertion sort.  *  *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Insertion < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *  *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *  *  % java Insertion < words3.txt  *  all bad bed bug dad ... yes yet zoo   [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; /**  *  The { @code  Insertion} class provides static methods for sorting an  *  array using insertion sort.  *  

 *  In the worst case, this implementation makes ~ ½ n2

 *  compares and ~ ½ n2 exchanges to sort an array

 *  of length n. So, it is not suitable for sorting large arbitrary

 *  arrays. More precisely, the number of exchanges is exactly equal to the

 *  number of inversions. So, for example, it sorts a partially-sorted array

 *  in linear time.

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(1) extra memory (not including the input array).

 *  

 *  See InsertionPedantic.java

 *  for a version that eliminates the compiler warning.

 *  

 *  For additional documentation, see Section 2.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Insertion
 
{

    
// This class should not be instantiated.

    
private
 
Insertion
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =  i ;  j  >
 
0
 
&&
 less
(
a
[
j
],
 a
[
j

1
]);
 j

)
 
{

                exch
(
a
,
 j
,
 j

1
);

            
}

            
assert
 isSorted
(
a
,
 
0
,
 i
);

        
}

        
assert
 isSorted
(
a
);

    
}

    
/**

     * Rearranges the subarray a[lo..hi) in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     * 
@param
 lo left endpoint (inclusive)

     * 
@param
 hi right endpoint (exclusive)

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{

        
for
 
(
int
 i 
=
 lo 
+
 
1
;
 i 
<  hi ;  i ++ )   {              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
]);
 j

)
 
{

                exch
(
a
,
 j
,
 j

1
);

            
}

        
}

        
assert
 isSorted
(
a
,
 lo
,
 hi
);

    
}

    
/**

     * Rearranges the array in ascending order, using a comparator.

     * 
@param
 a the array

     * 
@param
 comparator the comparator specifying the order

     */

    
public
 
static
 
void
 sort
(
Object
[]
 a
,
 
Comparator
 comparator
)
 
{

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              for   ( int  j  =  i ;  j  >
 
0
 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 comparator
);
 j

)
 
{

                exch
(
a
,
 j
,
 j

1
);

            
}

            
assert
 isSorted
(
a
,
 
0
,
 i
,
 comparator
);

        
}

        
assert
 isSorted
(
a
,
 comparator
);

    
}

    
/**

     * Rearranges the subarray a[lo..hi) in ascending order, using a comparator.

     * 
@param
 a the array

     * 
@param
 lo left endpoint (inclusive)

     * 
@param
 hi right endpoint (exclusive)

     * 
@param
 comparator the comparator specifying the order

     */

    
public
 
static
 
void
 sort
(
Object
[]
 a
,
 
int
 lo
,
 
int
 hi
,
 
Comparator
 comparator
)
 
{

        
for
 
(
int
 i 
=
 lo 
+
 
1
;
 i 
<  hi ;  i ++ )   {              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 comparator
);
 j

)
 
{

                exch
(
a
,
 j
,
 j

1
);

            
}

        
}

        
assert
 isSorted
(
a
,
 lo
,
 hi
,
 comparator
);

    
}

    
// return a permutation that gives the elements in a[] in ascending order

    
// do not change the original array a[]

    
/**

     * Returns a permutation that gives the elements in the array in ascending order.

     * 
@param
 a the array

     * 
@return
 a permutation {
@code
 p[]} such that {
@code
 a[p[0]]}, {
@code
 a[p[1]]},

     *    …, {
@code
 a[p[n-1]]} are in ascending order

     */

    
public
 
static
 
int
[]
 indexSort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
int
[]
 index 
=
 
new
 
int
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             index [ i ]   =  i ;          for   ( int  i  =   1 ;  i  <  n ;  i ++ )              for   ( int  j  =  i ;  j  >
 
0
 
&&
 less
(
a
[
index
[
j
]],
 a
[
index
[
j

1
]]);
 j

)

                exch
(
index
,
 j
,
 j

1
);

        
return
 index
;

    
}

   
/***************************************************************************

    *  Helper sorting functions.

    ***************************************************************************/

    

    
// is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }      // is v < w ?      private   static   boolean  less ( Object  v ,   Object  w ,   Comparator  comparator )   {          return  comparator . compare ( v ,  w )   <   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }      // exchange a[i] and a[j]  (for indirect sort)      private   static   void  exch ( int []  a ,   int  i ,   int  j )   {          int  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length );      }      // is the array a[lo..hi) sorted      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {          return  isSorted ( a ,   0 ,  a . length ,  comparator );      }      // is the array a[lo..hi) sorted      private   static   boolean  isSorted ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {          for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ],  comparator ))   return   false ;          return   true ;      }     // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; insertion sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Insertion . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/InsertionX.java edu/princeton/cs/algs4/InsertionX.java /******************************************************************************  *  Compilation:  javac InsertionX.java  *  Execution:    java InsertionX < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt  *                https://algs4.cs.princeton.edu/21elementary/words3.txt  *    *  Sorts a sequence of strings from standard input using an optimized  *  version of insertion sort that uses half exchanges instead of   *  full exchanges to reduce data movement..  *  *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java InsertionX < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *  *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *  *  % java InsertionX < words3.txt  *  all bad bed bug dad ... yes yet zoo   [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  InsertionX} class provides static methods for sorting  *  an array using an optimized version of insertion sort (with half exchanges  *  and a sentinel).  *  

 *  In the worst case, this implementation makes ~ 1/2 n2

 *  compares to sort an array of length n.

 *  So, it is not suitable for sorting large arrays

 *  (unless the number of inversions is small).

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(1) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
InsertionX
 
{

    
// This class should not be instantiated.

    
private
 
InsertionX
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
// put smallest element in position to serve as sentinel

        
int
 exchanges 
=
 
0
;

        
for
 
(
int
 i 
=
 n

1
;
 i 
>
 
0
;
 i

)
 
{

            
if
 
(
less
(
a
[
i
],
 a
[
i

1
]))
 
{

                exch
(
a
,
 i
,
 i

1
);

                exchanges
++
;

            
}

        
}

        
if
 
(
exchanges 
==
 
0
)
 
return
;

        
// insertion sort with half-exchanges

        
for
 
(
int
 i 
=
 
2
;
 i 
<  n ;  i ++ )   {              Comparable  v  =  a [ i ];              int  j  =  i ;              while   ( less ( v ,  a [ j - 1 ]))   {                 a [ j ]   =  a [ j - 1 ];                 j -- ;              }             a [ j ]   =  v ;          }          assert  isSorted ( a );      }     /***************************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; insertion sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          InsertionX . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Interval1D.java edu/princeton/cs/algs4/Interval1D.java /******************************************************************************  *  Compilation:  javac Interval1D.java  *  Execution:    java Interval1D  *  Dependencies: StdOut.java  *    *  1-dimensional interval data type.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; import  java . util . Comparator ; /**  *  The { @code  Interval1D} class represents a one-dimensional interval.  *  The interval is closed—it contains both endpoints.

 *  Intervals are immutable: their values cannot be changed after they are created.

 *  The class {
@code
 Interval1D} includes methods for checking whether

 *  an interval contains a point and determining whether two intervals intersect.

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Interval1D
 
{

    
/**

     * Compares two intervals by min endpoint.

     */

    
public
 
static
 
final
 
Comparator
< Interval1D >
 MIN_ENDPOINT_ORDER  
=
 
new
 
MinEndpointComparator
();

    
/**

     * Compares two intervals by max endpoint.

     */

    
public
 
static
 
final
 
Comparator
< Interval1D >
 MAX_ENDPOINT_ORDER 
=
 
new
 
MaxEndpointComparator
();

    
/**

     * Compares two intervals by length.

     */

    
public
 
static
 
final
 
Comparator
< Interval1D >
 LENGTH_ORDER 
=
 
new
 
LengthComparator
();

    
private
 
final
 
double
 min
;

    
private
 
final
 
double
 max
;

    
/**

     * Initializes a closed interval [min, max].

     *

     * 
@param
  min the smaller endpoint

     * 
@param
  max the larger endpoint

     * 
@throws
 IllegalArgumentException if the min endpoint is greater than the max endpoint

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max}

     *         is {
@code
 Double.NaN}, {
@code
 Double.POSITIVE_INFINITY} or

     *         {
@code
 Double.NEGATIVE_INFINITY}

     */

    
public
 
Interval1D
(
double
 min
,
 
double
 max
)
 
{

        
if
 
(
Double
.
isInfinite
(
min
)
 
||
 
Double
.
isInfinite
(
max
))

            
throw
 
new
 
IllegalArgumentException
(
“Endpoints must be finite”
);

        
if
 
(
Double
.
isNaN
(
min
)
 
||
 
Double
.
isNaN
(
max
))

            
throw
 
new
 
IllegalArgumentException
(
“Endpoints cannot be NaN”
);

        
// convert -0.0 to +0.0

        
if
 
(
min 
==
 
0.0
)
 min 
=
 
0.0
;

        
if
 
(
max 
==
 
0.0
)
 max 
=
 
0.0
;

        
if
 
(
min 
<=  max )   {              this . min  =  min ;              this . max  =  max ;          }          else   throw   new   IllegalArgumentException ( "Illegal interval" );      }      /**      * Returns the left endpoint of this interval.      *      *  @return  the left endpoint of this interval      *  @deprecated  Replaced by { @link  #min()}.      */     @ Deprecated      public   double  left ()   {            return  min ;      }      /**      * Returns the right endpoint of this interval.      *  @return  the right endpoint of this interval      *  @deprecated  Replaced by { @link  #max()}.      */     @ Deprecated      public   double  right ()   {            return  max ;      }      /**      * Returns the min endpoint of this interval.      *      *  @return  the min endpoint of this interval      */      public   double  min ()   {            return  min ;      }      /**      * Returns the max endpoint of this interval.      *      *  @return  the max endpoint of this interval      */      public   double  max ()   {            return  max ;      }      /**      * Returns true if this interval intersects the specified interval.      *      *  @param   that the other interval      *  @return  { @code  true} if this interval intersects the argument interval;      *         { @code  false} otherwise      */      public   boolean  intersects ( Interval1D  that )   {          if   ( this . max  <  that . min )   return   false ;          if   ( that . max  <   this . min )   return   false ;          return   true ;      }      /**      * Returns true if this interval contains the specified value.      *      *  @param  x the value      *  @return  { @code  true} if this interval contains the value { @code  x};      *         { @code  false} otherwise      */      public   boolean  contains ( double  x )   {          return   ( min  <=  x )   &&   ( x  <=  max );      }      /**      * Returns the length of this interval.      *      *  @return  the length of this interval (max - min)      */      public   double  length ()   {          return  max  -  min ;      }      /**      * Returns a string representation of this interval.      *      *  @return  a string representation of this interval in the form [min, max]      */      public   String  toString ()   {          return   "["   +  min  +   ", "   +  max  +   "]" ;      }      /**      * Compares this transaction to the specified object.      *      *  @param   other the other interval      *  @return  { @code  true} if this interval equals the other interval;      *         { @code  false} otherwise      */      public   boolean  equals ( Object  other )   {          if   ( other  ==   this )   return   true ;          if   ( other  ==   null )   return   false ;          if   ( other . getClass ()   !=   this . getClass ())   return   false ;          Interval1D  that  =   ( Interval1D )  other ;          return   this . min  ==  that . min  &&   this . max  ==  that . max ;      }      /**      * Returns an integer hash code for this interval.      *      *  @return  an integer hash code for this interval      */      public   int  hashCode ()   {          int  hash1  =   (( Double )  min ). hashCode ();          int  hash2  =   (( Double )  max ). hashCode ();          return   31 * hash1  +  hash2 ;      }      // ascending order of min endpoint, breaking ties by max endpoint      private   static   class   MinEndpointComparator   implements   Comparator < Interval1D >
 
{

        
public
 
int
 compare
(
Interval1D
 a
,
 
Interval1D
 b
)
 
{

            
if
      
(
a
.
min 
<  b . min )   return   - 1 ;              else   if   ( a . min  >
 b
.
min
)
 
return
 
+
1
;

            
else
 
if
 
(
a
.
max 
<  b . max )   return   - 1 ;              else   if   ( a . max  >
 b
.
max
)
 
return
 
+
1
;

            
else
                    
return
  
0
;

        
}

    
}

    
// ascending order of max endpoint, breaking ties by min endpoint

    
private
 
static
 
class
 
MaxEndpointComparator
 
implements
 
Comparator
< Interval1D >
 
{

        
public
 
int
 compare
(
Interval1D
 a
,
 
Interval1D
 b
)
 
{

            
if
      
(
a
.
max 
<  b . max )   return   - 1 ;              else   if   ( a . max  >
 b
.
max
)
 
return
 
+
1
;

            
else
 
if
 
(
a
.
min 
<  b . min )   return   - 1 ;              else   if   ( a . min  >
 b
.
min
)
 
return
 
+
1
;

            
else
                    
return
  
0
;

        
}

    
}

    
// ascending order of length

    
private
 
static
 
class
 
LengthComparator
 
implements
 
Comparator
< Interval1D >
 
{

        
public
 
int
 compare
(
Interval1D
 a
,
 
Interval1D
 b
)
 
{

            
double
 alen 
=
 a
.
length
();

            
double
 blen 
=
 b
.
length
();

            
if
      
(
alen 
<  blen )   return   - 1 ;              else   if   ( alen  >
 blen
)
 
return
 
+
1
;

            
else
                  
return
  
0
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 Interval1D} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Interval1D
[]
 intervals 
=
 
new
 
Interval1D
[
4
];

        intervals
[
0
]
 
=
 
new
 
Interval1D
(
15.0
,
 
33.0
);

        intervals
[
1
]
 
=
 
new
 
Interval1D
(
45.0
,
 
60.0
);

        intervals
[
2
]
 
=
 
new
 
Interval1D
(
20.0
,
 
70.0
);

        intervals
[
3
]
 
=
 
new
 
Interval1D
(
46.0
,
 
55.0
);

        
StdOut
.
println
(
“Unsorted”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  intervals . length ;  i ++ )              StdOut . println ( intervals [ i ]);          StdOut . println ();                   StdOut . println ( "Sort by min endpoint" );          Arrays . sort ( intervals ,   Interval1D . MIN_ENDPOINT_ORDER );          for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )              StdOut . println ( intervals [ i ]);          StdOut . println ();          StdOut . println ( "Sort by max endpoint" );          Arrays . sort ( intervals ,   Interval1D . MAX_ENDPOINT_ORDER );          for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )              StdOut . println ( intervals [ i ]);          StdOut . println ();          StdOut . println ( "Sort by length" );          Arrays . sort ( intervals ,   Interval1D . LENGTH_ORDER );          for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )              StdOut . println ( intervals [ i ]);          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Interval2D.java edu/princeton/cs/algs4/Interval2D.java /******************************************************************************  *  Compilation:  javac Interval2D.java  *  Execution:    java Interval2D  *  Dependencies: StdOut.java Interval1D.java StdDraw.java  *    *  2-dimensional interval data type.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Interval2D} class represents a closed two-dimensional interval,  *  which represents all points (x, y) with both { @code  xmin <= x <= xmax} and  *  { @code  ymin <= y <= ymax}.  *  Two-dimensional intervals are immutable: their values cannot be changed  *  after they are created.  *  The class { @code  Interval2D} includes methods for checking whether  *  a two-dimensional interval contains a point and determining whether  *  two two-dimensional intervals intersect.  *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Interval2D
 
{

    
private
 
final
 
Interval1D
 x
;

    
private
 
final
 
Interval1D
 y
;

    
/**

     * Initializes a two-dimensional interval.

     * 
@param
 x the one-dimensional interval of x-coordinates

     * 
@param
 y the one-dimensional interval of y-coordinates

     */

    
public
 
Interval2D
(
Interval1D
 x
,
 
Interval1D
 y
)
 
{

        
this
.

=
 x
;

        
this
.

=
 y
;

    
}

    
/**

     * Does this two-dimensional interval intersect that two-dimensional interval?

     * 
@param
 that the other two-dimensional interval

     * 
@return
 true if this two-dimensional interval intersects

     *    that two-dimensional interval; false otherwise

     */

    
public
 
boolean
 intersects
(
Interval2D
 that
)
 
{

        
if
 
(
!
this
.
x
.
intersects
(
that
.
x
))
 
return
 
false
;

        
if
 
(
!
this
.
y
.
intersects
(
that
.
y
))
 
return
 
false
;

        
return
 
true
;

    
}

    
/**

     * Does this two-dimensional interval contain the point p?

     * 
@param
 p the two-dimensional point

     * 
@return
 true if this two-dimensional interval contains the point p; false otherwise

     */

    
public
 
boolean
 contains
(
Point2D
 p
)
 
{

        
return
 x
.
contains
(
p
.
x
())
  
&&
 y
.
contains
(
p
.
y
());

    
}

    
/**

     * Returns the area of this two-dimensional interval.

     * 
@return
 the area of this two-dimensional interval

     */

    
public
 
double
 area
()
 
{

        
return
 x
.
length
()
 
*
 y
.
length
();

    
}

        

    
/**

     * Returns a string representation of this two-dimensional interval.

     * 
@return
 a string representation of this two-dimensional interval

     *    in the form [xmin, xmax] x [ymin, ymax]

     */

    
public
 
String
 toString
()
 
{

        
return
 x 
+
 
” x ”
 
+
 y
;

    
}

    
/**

     * Does this interval equal the other interval?

     * 
@param
 other the other interval

     * 
@return
 true if this interval equals the other interval; false otherwise

     */

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
Interval2D
 that 
=
 
(
Interval2D
)
 other
;

        
return
 
this
.
x
.
equals
(
that
.
x
)
 
&&
 
this
.
y
.
equals
(
that
.
y
);

    
}

 

    
/**

     * Returns an integer hash code for this interval.  

     * 
@return
 an integer hash code for this interval 

     */

    
public
 
int
 hashCode
()
 
{

        
int
 hash1 
=
 x
.
hashCode
();

        
int
 hash2 
=
 y
.
hashCode
();

        
return
 
31
*
hash1 
+
 hash2
;

    
}

    
/**

     * Draws this two-dimensional interval to standard draw.

     */

    
public
 
void
 draw
()
 
{

        
double
 xc 
=
 
(
x
.
min
()
 
+
 x
.
max
())
 
/
 
2.0
;

        
double
 yc 
=
 
(
y
.
min
()
 
+
 y
.
max
())
 
/
 
2.0
;

        
StdDraw
.
rectangle
(
xc
,
 yc
,
 x
.
length
()
 
/
 
2.0
,
 y
.
length
()
 
/
 
2.0
);

    
}

    
/**

     * Unit tests the {
@code
 Interval2D} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
double
 xmin 
=
 
Double
.
parseDouble
(
args
[
0
]);

        
double
 xmax 
=
 
Double
.
parseDouble
(
args
[
1
]);

        
double
 ymin 
=
 
Double
.
parseDouble
(
args
[
2
]);

        
double
 ymax 
=
 
Double
.
parseDouble
(
args
[
3
]);

        
int
 trials 
=
 
Integer
.
parseInt
(
args
[
4
]);

        
Interval1D
 xInterval 
=
 
new
 
Interval1D
(
xmin
,
 xmax
);

        
Interval1D
 yInterval 
=
 
new
 
Interval1D
(
ymin
,
 ymax
);

        
Interval2D
 box 
=
 
new
 
Interval2D
(
xInterval
,
 yInterval
);

        box
.
draw
();

        
Counter
 counter 
=
 
new
 
Counter
(
“hits”
);

        
for
 
(
int
 t 
=
 
0
;
 t 
<  trials ;  t ++ )   {              double  x  =   StdRandom . uniform ( 0.0 ,   1.0 );              double  y  =   StdRandom . uniform ( 0.0 ,   1.0 );              Point2D  point  =   new   Point2D ( x ,  y );              if   ( box . contains ( point ))  counter . increment ();              else                      point . draw ();          }          StdOut . println ( counter );          StdOut . printf ( "box area = %.2f\n" ,  box . area ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Inversions.java edu/princeton/cs/algs4/Inversions.java /******************************************************************************  *  Compilation:  javac Inversions.java  *  Execution:    java Inversions < input.txt  *  Dependencies: StdIn.java StdOut.java  *    *  Read array of n integers and count number of inversions in n log n time.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Inversions} class provides static methods to count the   *  number of inversions in either an array of integers or comparables.

 *  An inversion in an array {
@code
 a[]} is a pair of indicies {
@code
 i} and

 *  {
@code
 j} such that {
@code
 i < j} and { @code  a[i] > a[j]}.

 *  

 *  This implementation uses a generalization of mergesort. The count

 *  operation takes Θ(n log n) time to count the

 *  number of inversions in any array of length n (assuming

 *  comparisons take constant time).

 *  

 *  For additional documentation, see

 *  Section 2.2

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Inversions
 
{

    
// do not instantiate

    
private
 
Inversions
()
 
{
 
}

    
// merge and count

    
private
 
static
 
long
 merge
(
int
[]
 a
,
 
int
[]
 aux
,
 
int
 lo
,
 
int
 mid
,
 
int
 hi
)
 
{

        
long
 inversions 
=
 
0
;

        
// copy to aux[]

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  hi ;  k ++ )   {             aux [ k ]   =  a [ k ];            }          // merge back to a[]          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
           a
[
k
]
 
=
 aux
[
j
++
];

            
else
 
if
 
(

>
 hi
)
            a
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
aux
[
j
]
 
<  aux [ i ])   {  a [ k ]   =  aux [ j ++ ];  inversions  +=   ( mid  -  i  +   1 );   }              else                         a [ k ]   =  aux [ i ++ ];          }          return  inversions ;      }      // return the number of inversions in the subarray b[lo..hi]      // side effect b[lo..hi] is rearranged in ascending order      private   static   long  count ( int []  a ,   int []  b ,   int []  aux ,   int  lo ,   int  hi )   {          long  inversions  =   0 ;          if   ( hi  <=  lo )   return   0 ;          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         inversions  +=  count ( a ,  b ,  aux ,  lo ,  mid );            inversions  +=  count ( a ,  b ,  aux ,  mid + 1 ,  hi );         inversions  +=  merge ( b ,  aux ,  lo ,  mid ,  hi );          assert  inversions  ==  brute ( a ,  lo ,  hi );          return  inversions ;      }      /**      * Returns the number of inversions in the integer array.      * The argument array is not modified.      *  @param   a the array      *  @return  the number of inversions in the array. An inversion is a pair of       *         indicies { @code  i} and { @code  j} such that { @code  i < j}      *         and { @code  a[i] > a[j]}.

     */

    
public
 
static
 
long
 count
(
int
[]
 a
)
 
{

        
int
[]
 b   
=
 
new
 
int
[
a
.
length
];

        
int
[]
 aux 
=
 
new
 
int
[
a
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )             b [ i ]   =  a [ i ];          long  inversions  =  count ( a ,  b ,  aux ,   0 ,  a . length  -   1 );          return  inversions ;      }      // merge and count (Comparable version)      private   static   < Key   extends   Comparable < Key >>
 
long
 merge
(
Key
[]
 a
,
 
Key
[]
 aux
,
 
int
 lo
,
 
int
 mid
,
 
int
 hi
)
 
{

        
long
 inversions 
=
 
0
;

        
// copy to aux[]

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  hi ;  k ++ )   {             aux [ k ]   =  a [ k ];            }          // merge back to a[]          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
                a
[
k
]
 
=
 aux
[
j
++
];

            
else
 
if
 
(

>
 hi
)
                 a
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
less
(
aux
[
j
],
 aux
[
i
]))
 
{
 a
[
k
]
 
=
 aux
[
j
++
];
 inversions 
+=
 
(
mid 

 i 
+
 
1
);
 
}

            
else
                             a
[
k
]
 
=
 aux
[
i
++
];

        
}

        
return
 inversions
;

    
}

    
// return the number of inversions in the subarray b[lo..hi]

    
// side effect b[lo..hi] is rearranged in ascending order

    
private
 
static
 
< Key   extends   Comparable < Key >>
 
long
 count
(
Key
[]
 a
,
 
Key
[]
 b
,
 
Key
[]
 aux
,
 
int
 lo
,
 
int
 hi
)
 
{

        
long
 inversions 
=
 
0
;

        
if
 
(
hi 
<=  lo )   return   0 ;          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         inversions  +=  count ( a ,  b ,  aux ,  lo ,  mid );            inversions  +=  count ( a ,  b ,  aux ,  mid + 1 ,  hi );         inversions  +=  merge ( b ,  aux ,  lo ,  mid ,  hi );          assert  inversions  ==  brute ( a ,  lo ,  hi );          return  inversions ;      }      /**      * Returns the number of inversions in the comparable array.      * The argument array is not modified.      *  @param   a the array      *  @param   the inferred type of the elements in the array

     * 
@return
 the number of inversions in the array. An inversion is a pair of 

     *         indicies {
@code
 i} and {
@code
 j} such that {
@code
 i < j}      *         and { @code  a[i].compareTo(a[j]) > 0}.

     */

    
public
 
static
 
< Key   extends   Comparable < Key >>
 
long
 count
(
Key
[]
 a
)
 
{

        
Key
[]
 b   
=
 a
.
clone
();

        
Key
[]
 aux 
=
 a
.
clone
();

        
long
 inversions 
=
 count
(
a
,
 b
,
 aux
,
 
0
,
 a
.
length 

 
1
);

        
return
 inversions
;

    
}

    
// is v < w ?      private   static   < Key   extends   Comparable < Key >>
 
boolean
 less
(
Key
 v
,
 
Key
 w
)
 
{

        
return
 
(
v
.
compareTo
(
w
)
 
<   0 );      }      // count number of inversions in a[lo..hi] via brute force (for debugging only)      private   static   < Key   extends   Comparable < Key >>
 
long
 brute
(
Key
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{

        
long
 inversions 
=
 
0
;

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )              for   ( int  j  =  i  +   1 ;  j  <=  hi ;  j ++ )                  if   ( less ( a [ j ],  a [ i ]))  inversions ++ ;          return  inversions ;      }      // count number of inversions in a[lo..hi] via brute force (for debugging only)      private   static   long  brute ( int []  a ,   int  lo ,   int  hi )   {          long  inversions  =   0 ;          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i  +   1 ;  j  <=  hi ;  j ++ )                  if   ( a [ j ]   <  a [ i ])  inversions ++ ;          return  inversions ;      }      /**      * Reads a sequence of integers from standard input and      * prints the number of inversions to standard output.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int []  a  =   StdIn . readAllInts ();          int  n  =  a . length ;          Integer []  b  =   new   Integer [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             b [ i ]   =  a [ i ];          StdOut . println ( Inversions . count ( a ));          StdOut . println ( Inversions . count ( b ));      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/KMP.java edu/princeton/cs/algs4/KMP.java /******************************************************************************  *  Compilation:  javac KMP.java  *  Execution:    java KMP pattern text  *  Dependencies: StdOut.java  *  *  Reads in two strings, the pattern and the input text, and  *  searches for the pattern in the input text using the  *  KMP algorithm.  *  *  % java KMP abracadabra abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:               abracadabra            *  *  % java KMP rab abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:         rab  *  *  % java KMP bcara abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad   *  pattern:                                   bcara  *  *  % java KMP rabrabracad abacadabrabracabracadabrabrabracad   *  text:    abacadabrabracabracadabrabrabracad  *  pattern:                        rabrabracad  *  *  % java KMP abacad abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad  *  pattern: abacad  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  KMP} class finds the first occurrence of a pattern string  *  in a text string.  *  

 *  This implementation uses a version of the Knuth-Morris-Pratt substring search

 *  algorithm. The version takes time proportional to n + m R

 *  in the worst case, where n is the length of the text string,

 *  m is the length of the pattern, and R is the alphabet size.

 *  It uses extra space proportional to m R.

 *  

 *  For additional documentation,

 *  see Section 5.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 KMP 
{

    
private
 
final
 
int
 R
;
       
// the radix

    
private
 
int
[][]
 dfa
;
       
// the KMP automoton

    
private
 
char
[]
 pattern
;
    
// either the character array for the pattern

    
private
 
String
 pat
;
        
// or the pattern string

    
/**

     * Preprocesses the pattern string.

     *

     * 
@param
 pat the pattern string

     */

    
public
 KMP
(
String
 pat
)
 
{

        
this
.

=
 
256
;

        
this
.
pat 
=
 pat
;

        
// build DFA from pattern

        
int
 m 
=
 pat
.
length
();

        dfa 
=
 
new
 
int
[
R
][
m
];
 

        dfa
[
pat
.
charAt
(
0
)][
0
]
 
=
 
1
;
 

        
for
 
(
int
 x 
=
 
0
,
 j 
=
 
1
;
 j 
<  m ;  j ++ )   {              for   ( int  c  =   0 ;  c  <  R ;  c ++ )                   dfa [ c ][ j ]   =  dfa [ c ][ x ];       // Copy mismatch cases.              dfa [ pat . charAt ( j )][ j ]   =  j + 1 ;     // Set match case.              x  =  dfa [ pat . charAt ( j )][ x ];       // Update restart state.           }        }        /**      * Preprocesses the pattern string.      *      *  @param  pattern the pattern string      *  @param  R the alphabet size      */      public  KMP ( char []  pattern ,   int  R )   {          this . R  =  R ;          this . pattern  =   new   char [ pattern . length ];          for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )              this . pattern [ j ]   =  pattern [ j ];          // build DFA from pattern          int  m  =  pattern . length ;         dfa  =   new   int [ R ][ m ];           dfa [ pattern [ 0 ]][ 0 ]   =   1 ;            for   ( int  x  =   0 ,  j  =   1 ;  j  <  m ;  j ++ )   {              for   ( int  c  =   0 ;  c  <  R ;  c ++ )                   dfa [ c ][ j ]   =  dfa [ c ][ x ];       // Copy mismatch cases.              dfa [ pattern [ j ]][ j ]   =  j + 1 ;        // Set match case.              x  =  dfa [ pattern [ j ]][ x ];          // Update restart state.           }        }        /**      * Returns the index of the first occurrrence of the pattern string      * in the text string.      *      *  @param   txt the text string      *  @return  the index of the first occurrence of the pattern string      *         in the text string; N if no such match      */      public   int  search ( String  txt )   {          // simulate operation of DFA on text          int  m  =  pat . length ();          int  n  =  txt . length ();          int  i ,  j ;          for   ( i  =   0 ,  j  =   0 ;  i  <  n  &&  j  <  m ;  i ++ )   {             j  =  dfa [ txt . charAt ( i )][ j ];          }          if   ( j  ==  m )   return  i  -  m ;      // found          return  n ;                      // not found      }      /**      * Returns the index of the first occurrrence of the pattern string      * in the text string.      *      *  @param   text the text string      *  @return  the index of the first occurrence of the pattern string      *         in the text string; N if no such match      */      public   int  search ( char []  text )   {          // simulate operation of DFA on text          int  m  =  pattern . length ;          int  n  =  text . length ;          int  i ,  j ;          for   ( i  =   0 ,  j  =   0 ;  i  <  n  &&  j  <  m ;  i ++ )   {             j  =  dfa [ text [ i ]][ j ];          }          if   ( j  ==  m )   return  i  -  m ;      // found          return  n ;                      // not found      }      /**       * Takes a pattern string and an input string as command-line arguments;      * searches for the pattern string in the text string; and prints      * the first occurrence of the pattern string in the text string.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String  pat  =  args [ 0 ];          String  txt  =  args [ 1 ];          char []  pattern  =  pat . toCharArray ();          char []  text     =  txt . toCharArray ();         KMP kmp1  =   new  KMP ( pat );          int  offset1  =  kmp1 . search ( txt );         KMP kmp2  =   new  KMP ( pattern ,   256 );          int  offset2  =  kmp2 . search ( text );          // print results          StdOut . println ( "text:    "   +  txt );          StdOut . print ( "pattern: " );          for   ( int  i  =   0 ;  i  <  offset1 ;  i ++ )              StdOut . print ( " " );          StdOut . println ( pat );          StdOut . print ( "pattern: " );          for   ( int  i  =   0 ;  i  <  offset2 ;  i ++ )              StdOut . print ( " " );          StdOut . println ( pat );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Knuth.java edu/princeton/cs/algs4/Knuth.java /******************************************************************************  *  Compilation:  javac Knuth.java  *  Execution:    java Knuth < list.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/11model/cards.txt  *                https://algs4.cs.princeton.edu/11model/cardsUnicode.txt  *    *  Reads in a list of strings and prints them in random order.  *  The Knuth (or Fisher-Yates) shuffling algorithm guarantees  *  to rearrange the elements in uniformly random order, under  *  the assumption that Math.random() generates independent and  *  uniformly distributed numbers between 0 and 1.  *  *  % more cards.txt  *  2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC AC  *  2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD AD  *  2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH AH  *  2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS AS  *  *  % java Knuth < cards.txt  *  6H  *  9C  *  8H  *  7C  *  JS  *  ...  *  KH  *  *  % more cardsUnicode.txt  *  2♣ 3♣ 4♣ 5♣ 6♣ 7♣ 8♣ 9♣ 10♣ J♣ Q♣ K♣ A♣   *  2♦ 3♦ 4♦ 5♦ 6♦ 7♦ 8♦ 9♦ 10♦ J♦ Q♦ K♦ A♦   *  2♥ 3♥ 4♥ 5♥ 6♥ 7♥ 8♥ 9♥ 10♥ J♥ Q♥ K♥ A♥   *  2♠ 3♠ 4♠ 5♠ 6♠ 7♠ 8♠ 9♠ 10♠ J♠ Q♠ K♠ A♠   *   *  % java Knuth < cardsUnicode.txt  *  2♠  *  K♥  *  6♥  *  5♣  *  J♣  *  ...  *  A♦  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Knuth} class provides a client for reading in a   *  sequence of strings and shuffling them using the Knuth (or Fisher-Yates)

 *  shuffling algorithm. This algorithm guarantees to rearrange the

 *  elements in uniformly random order, under

 *  the assumption that Math.random() generates independent and

 *  uniformly distributed numbers between 0 and 1.

 *  

 *  For additional documentation,

 *  see Section 1.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  See {
@link
 StdRandom} for versions that shuffle arrays and

 *  subarrays of objects, doubles, and ints.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Knuth
 
{
 

    
// this class should not be instantiated

    
private
 
Knuth
()
 
{
 
}

    
/**

     * Rearranges an array of objects in uniformly random order

     * (under the assumption that {
@code
 Math.random()} generates independent

     * and uniformly distributed numbers between 0 and 1).

     * 
@param
 a the array to be shuffled

     */

    
public
 
static
 
void
 shuffle
(
Object
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              // choose index uniformly in [0, i]              int  r  =   ( int )   ( Math . random ()   *   ( i  +   1 ));              Object  swap  =  a [ r ];             a [ r ]   =  a [ i ];             a [ i ]   =  swap ;          }      }      /**      * Rearranges an array of objects in uniformly random order      * (under the assumption that { @code  Math.random()} generates independent      * and uniformly distributed numbers between 0 and 1).      *  @param  a the array to be shuffled      */      public   static   void  shuffleAlternate ( Object []  a )   {          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              // choose index uniformly in [i, n-1]              int  r  =  i  +   ( int )   ( Math . random ()   *   ( n  -  i ));              Object  swap  =  a [ r ];             a [ r ]   =  a [ i ];             a [ i ]   =  swap ;          }      }      /**      * Reads in a sequence of strings from standard input, shuffles      * them, and prints out the results.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read in the data          String []  a  =   StdIn . readAllStrings ();          // shuffle the array          Knuth . shuffle ( a );          // print results.          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/KosarajuSharirSCC.java edu/princeton/cs/algs4/KosarajuSharirSCC.java /******************************************************************************  *  Compilation:  javac KosarajuSharirSCC.java  *  Execution:    java KosarajuSharirSCC filename.txt  *  Dependencies: Digraph.java TransitiveClosure.java StdOut.java In.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt  *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt  *  *  Compute the strongly-connected components of a digraph using the  *  Kosaraju-Sharir algorithm.  *  *  Runs in O(E + V) time.  *  *  % java KosarajuSharirSCC tinyDG.txt  *  5 strong components  *  1   *  0 2 3 4 5   *  9 10 11 12   *  6 8   *  7  *  *  % java KosarajuSharirSCC mediumDG.txt   *  10 strong components  *  21   *  2 5 6 8 9 11 12 13 15 16 18 19 22 23 25 26 28 29 30 31 32 33 34 35 37 38 39 40 42 43 44 46 47 48 49   *  14   *  3 4 17 20 24 27 36   *  41   *  7   *  45   *  1   *  0   *  10   *  *  % java -Xss50m KosarajuSharirSCC mediumDG.txt   *  25 strong components  *  7 11 32 36 61 84 95 116 121 128 230   ...  *  28 73 80 104 115 143 149 164 184 185  ...  *  38 40 200 201 207 218 286 387 418 422 ...  *  12 14 56 78 87 103 216 269 271 272    ...  *  42 48 112 135 160 217 243 246 273 346 ...  *  46 76 96 97 224 237 297 303 308 309   ...  *  9 15 21 22 27 90 167 214 220 225 227  ...  *  74 99 133 146 161 166 202 205 245 262 ...  *  43 83 94 120 125 183 195 206 244 254  ...  *  1 13 54 91 92 93 106 140 156 194 208  ...  *  10 39 67 69 131 144 145 154 168 258   ...  *  6 52 66 113 118 122 139 147 212 213   ...  *  8 127 150 182 203 204 249 367 400 432 ...  *  63 65 101 107 108 136 169 170 171 173 ...  *  55 71 102 155 159 198 228 252 325 419 ...  *  4 25 34 58 70 152 172 196 199 210 226 ...  *  2 44 50 88 109 138 141 178 197 211    ...  *  57 89 129 162 174 179 188 209 238 276 ...  *  33 41 49 119 126 132 148 181 215 221  ...  *  3 18 23 26 35 64 105 124 157 186 251  ...  *  5 16 17 20 31 47 81 98 158 180 187    ...  *  24 29 51 59 75 82 100 114 117 134 151 ...  *  30 45 53 60 72 85 111 130 137 142 163 ...  *  19 37 62 77 79 110 153 352 353 361    ...  *  0 68 86 123 165 176 193 239 289 336   ...  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  KosarajuSharirSCC} class represents a data type for   *  determining the strong components in a digraph.  *  The id operation determines in which strong component

 *  a given vertex lies; the areStronglyConnected operation

 *  determines whether two vertices are in the same strong component;

 *  and the count operation determines the number of strong

 *  components.

 *  

 *  The component identifier of a component is one of the

 *  vertices in the strong component: two vertices have the same component

 *  identifier if and only if they are in the same strong component.

 *  

 *  This implementation uses the Kosaraju-Sharir algorithm.

 *  The constructor takes Θ(V + E) time,

 *  where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  For alternative implementations of the same API, see

 *  {
@link
 TarjanSCC} and {
@link
 GabowSCC}.

 *  

 *  For additional documentation, see

 *  Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
KosarajuSharirSCC
 
{

    
private
 
boolean
[]
 marked
;
     
// marked[v] = has vertex v been visited?

    
private
 
int
[]
 id
;
             
// id[v] = id of strong component containing v

    
private
 
int
 count
;
            
// number of strongly-connected components

    
/**

     * Computes the strong components of the digraph {
@code
 G}.

     * 
@param
 G the digraph

     */

    
public
 
KosarajuSharirSCC
(
Digraph
 G
)
 
{

        
// compute reverse postorder of reverse graph

        
DepthFirstOrder
 dfs 
=
 
new
 
DepthFirstOrder
(
G
.
reverse
());

        
// run DFS on G, using reverse postorder to guide calculation

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        id 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
:
 dfs
.
reversePost
())
 
{

            
if
 
(
!
marked
[
v
])
 
{

                dfs
(
G
,
 v
);

                count
++
;

            
}

        
}

        
// check that id[] gives strong components

        
assert
 check
(
G
);

    
}

    
// DFS on graph G

    
private
 
void
 dfs
(
Digraph
 G
,
 
int
 v
)
 
{
 

        marked
[
v
]
 
=
 
true
;

        id
[
v
]
 
=
 count
;

        
for
 
(
int
 w 
:
 G
.
adj
(
v
))
 
{

            
if
 
(
!
marked
[
w
])
 dfs
(
G
,
 w
);

        
}

    
}

    
/**

     * Returns the number of strong components.

     * 
@return
 the number of strong components

     */

    
public
 
int
 count
()
 
{

        
return
 count
;

    
}

    
/**

     * Are vertices {
@code
 v} and {
@code
 w} in the same strong component?

     * 
@param
  v one vertex

     * 
@param
  w the other vertex

     * 
@return
 {
@code
 true} if vertices {
@code
 v} and {
@code
 w} are in the same

     *         strong component, and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      */      public   boolean  stronglyConnected ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  id [ v ]   ==  id [ w ];      }      /**      * Returns the component id of the strong component containing vertex { @code  v}.      *  @param   v the vertex      *  @return  the component id of the strong component containing vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= s < V}      */      public   int  id ( int  v )   {         validateVertex ( v );          return  id [ v ];      }      // does the id[] array contain the strongly connected components?      private   boolean  check ( Digraph  G )   {          TransitiveClosure  tc  =   new   TransitiveClosure ( G );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))                      return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 KosarajuSharirSCC} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
KosarajuSharirSCC
 scc 
=
 
new
 
KosarajuSharirSCC
(
G
);

        
// number of connected components

        
int
 m 
=
 scc
.
count
();

        
StdOut
.
println
(

+
 
” strong components”
);

        
// compute list of vertices in each strong component

        
Queue
< Integer >
[]
 components 
=
 
(
Queue
< Integer >
[])
 
new
 
Queue
[
m
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {             components [ i ]   =   new   Queue < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             components [ scc . id ( v )]. enqueue ( v );          }          // print results          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  v  :  components [ i ])   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/KruskalMST.java edu/princeton/cs/algs4/KruskalMST.java /******************************************************************************  *  Compilation:  javac KruskalMST.java  *  Execution:    java  KruskalMST filename.txt  *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java MinPQ.java  *                UF.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt  *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt  *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt  *  *  Compute a minimum spanning forest using Kruskal's algorithm.  *  *  %  java KruskalMST tinyEWG.txt   *  0-7 0.16000  *  2-3 0.17000  *  1-7 0.19000  *  0-2 0.26000  *  5-7 0.28000  *  4-5 0.35000  *  6-2 0.40000  *  1.81000  *  *  % java KruskalMST mediumEWG.txt  *  168-231 0.00268  *  151-208 0.00391  *  7-157   0.00516  *  122-205 0.00647  *  8-152   0.00702  *  156-219 0.00745  *  28-198  0.00775  *  38-126  0.00845  *  10-123  0.00886  *  ...  *  10.46351  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  KruskalMST} class represents a data type for computing a  *  minimum spanning tree in an edge-weighted graph.

 *  The edge weights can be positive, zero, or negative and need not

 *  be distinct. If the graph is not connected, it computes a minimum

 *  spanning forest, which is the union of minimum spanning trees

 *  in each connected component. The {
@code
 weight()} method returns the 

 *  weight of a minimum spanning tree and the {
@code
 edges()} method

 *  returns its edges.

 *  

 *  This implementation uses Krusal’s algorithm and the

 *  union-find data type.

 *  The constructor takes Θ(E log E) time in

 *  the worst case.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(E) extra space (not including the graph).

 *  

 *  For additional documentation,

 *  see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For alternate implementations, see {
@link
 LazyPrimMST}, {
@link
 PrimMST},

 *  and {
@link
 BoruvkaMST}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
KruskalMST
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-12
;

    
private
 
double
 weight
;
                        
// weight of MST

    
private
 
Queue
< Edge >
 mst 
=
 
new
 
Queue
< Edge >
();
  
// edges in MST

    
/**

     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.

     * 
@param
 G the edge-weighted graph

     */

    
public
 
KruskalMST
(
EdgeWeightedGraph
 G
)
 
{

        
// more efficient to build heap by passing array of edges

        
MinPQ
< Edge >
 pq 
=
 
new
 
MinPQ
< Edge >
();

        
for
 
(
Edge
 e 
:
 G
.
edges
())
 
{

            pq
.
insert
(
e
);

        
}

        
// run greedy algorithm

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
while
 
(
!
pq
.
isEmpty
()
 
&&
 mst
.
size
()
 
<  G . V ()   -   1 )   {              Edge  e  =  pq . delMin ();              int  v  =  e . either ();              int  w  =  e . other ( v );              if   ( uf . find ( v )   !=  uf . find ( w ))   {   // v-w does not create a cycle                 uf . union ( v ,  w );    // merge v and w components                 mst . enqueue ( e );    // add edge e to mst                 weight  +=  e . weight ();              }          }          // check optimality conditions          assert  check ( G );      }      /**      * Returns the edges in a minimum spanning tree (or forest).      *  @return  the edges in a minimum spanning tree (or forest) as      *    an iterable of edges      */      public   Iterable < Edge >
 edges
()
 
{

        
return
 mst
;

    
}

    
/**

     * Returns the sum of the edge weights in a minimum spanning tree (or forest).

     * 
@return
 the sum of the edge weights in a minimum spanning tree (or forest)

     */

    
public
 
double
 weight
()
 
{

        
return
 weight
;

    
}

    

    
// check optimality conditions (takes time proportional to E V lg* V)

    
private
 
boolean
 check
(
EdgeWeightedGraph
 G
)
 
{

        
// check total weight

        
double
 total 
=
 
0.0
;

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            total 
+=
 e
.
weight
();

        
}

        
if
 
(
Math
.
abs
(
total 

 weight
())
 
>
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
printf
(
“Weight of edges does not equal weight(): %f vs. %f\n”
,
 total
,
 weight
());

            
return
 
false
;

        
}

        
// check that it is acyclic

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
==
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a forest”
);

                
return
 
false
;

            
}

            uf
.
union
(
v
,
 w
);

        
}

        
// check that it is a spanning forest

        
for
 
(
Edge
 e 
:
 G
.
edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
!=
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a spanning forest”
);

                
return
 
false
;

            
}

        
}

        
// check that it is a minimal spanning forest (cut optimality conditions)

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
// all edges in MST except e

            uf 
=
 
new
 UF
(
G
.
V
());

            
for
 
(
Edge
 f 
:
 mst
)
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(

!=
 e
)
 uf
.
union
(
x
,
 y
);

            
}

            

            
// check that e is min weight edge in crossing cut

            
for
 
(
Edge
 f 
:
 G
.
edges
())
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(
uf
.
find
(
x
)
 
!=
 uf
.
find
(
y
))
 
{

                    
if
 
(
f
.
weight
()
 
<  e . weight ())   {                          System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );                          return   false ;                      }                  }              }          }          return   true ;      }      /**      * Unit tests the { @code  KruskalMST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );          KruskalMST  mst  =   new   KruskalMST ( G );          for   ( Edge  e  :  mst . edges ())   {              StdOut . println ( e );          }          StdOut . printf ( "%.5f\n" ,  mst . weight ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/KWIK.java edu/princeton/cs/algs4/KWIK.java /******************************************************************************  *  Compilation:  javac KWIK.java  *  Execution:    java KWIK file.txt  *  Dependencies: StdIn.java StdOut.java In.java SuffixArray.java  *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt  *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt   *  *  Keyword-in-context search.  *  *  %  java KWIK tale.txt 15  *  majesty  *   most gracious majesty king george th  *  rnkeys and the majesty of the law fir  *  on against the majesty of the people   *  se them to his majestys chief secreta  *  h lists of his majestys forces and of  *  *  the worst  *  w the best and the worst are known to y  *  f them give me the worst first there th  *  for in case of the worst is a friend in  *  e roomdoor and the worst is over then a  *  pect mr darnay the worst its the wisest  *  is his brother the worst of a bad race   *  ss in them for the worst of health for   *   you have seen the worst of her agitati  *  cumwented into the worst of luck buuust  *  n your brother the worst of the bad rac  *   full share in the worst of the day pla  *  mes to himself the worst of the strife   *  f times it was the worst of times it wa  *  ould hope that the worst was over well   *  urage business the worst will be over i  *  clesiastics of the worst world worldly   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  KWIK} class provides a { @link  SuffixArray} client for computing  *  all occurrences of a keyword in a given string, with surrounding context.  *  This is known as keyword-in-context search.

 *  

 *  For additional documentation,

 *  see Section 6.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 KWIK 
{

    
// Do not instantiate.

    
private
 KWIK
()
 
{
 
}

    
/**

     * Reads a string from a file specified as the first

     * command-line argument; read an integer k specified as the

     * second command line argument; then repeatedly processes

     * use queries, printing all occurrences of the given query

     * string in the text string with k characters of surrounding

     * context on either side.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
 context 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
// read in text

        
String
 text 
=
 in
.
readAll
().
replaceAll
(
“\\s+”
,
 
” ”
);

        
int
 n 
=
 text
.
length
();

        
// build suffix array

        
SuffixArray
 sa 
=
 
new
 
SuffixArray
(
text
);

        
// find all occurrences of queries and give context

        
while
 
(
StdIn
.
hasNextLine
())
 
{

            
String
 query 
=
 
StdIn
.
readLine
();

            
for
 
(
int
 i 
=
 sa
.
rank
(
query
);
 i 
<  n ;  i ++ )   {                  int  from1  =  sa . index ( i );                  int  to1    =   Math . min ( n ,  from1  +  query . length ());                  if   ( ! query . equals ( text . substring ( from1 ,  to1 )))   break ;                  int  from2  =   Math . max ( 0 ,  sa . index ( i )   -  context );                  int  to2    =   Math . min ( n ,  sa . index ( i )   +  context  +  query . length ());                  StdOut . println ( text . substring ( from2 ,  to2 ));              }              StdOut . println ();          }      }   }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/LazyPrimMST.java edu/princeton/cs/algs4/LazyPrimMST.java /******************************************************************************  *  Compilation:  javac LazyPrimMST.java  *  Execution:    java LazyPrimMST filename.txt  *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java  *                MinPQ.java UF.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt  *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt  *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt  *  *  Compute a minimum spanning forest using a lazy version of Prim's   *  algorithm.  *  *  %  java LazyPrimMST tinyEWG.txt   *  0-7 0.16000  *  1-7 0.19000  *  0-2 0.26000  *  2-3 0.17000  *  5-7 0.28000  *  4-5 0.35000  *  6-2 0.40000  *  1.81000  *  *  % java LazyPrimMST mediumEWG.txt  *  0-225   0.02383  *  49-225  0.03314  *  44-49   0.02107  *  44-204  0.01774  *  49-97   0.03121  *  202-204 0.04207  *  176-202 0.04299  *  176-191 0.02089  *  68-176  0.04396  *  58-68   0.04795  *  10.46351  *  *  % java LazyPrimMST largeEWG.txt  *  ...  *  647.66307  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  LazyPrimMST} class represents a data type for computing a  *  minimum spanning tree in an edge-weighted graph.

 *  The edge weights can be positive, zero, or negative and need not

 *  be distinct. If the graph is not connected, it computes a minimum

 *  spanning forest, which is the union of minimum spanning trees

 *  in each connected component. The {
@code
 weight()} method returns the 

 *  weight of a minimum spanning tree and the {
@code
 edges()} method

 *  returns its edges.

 *  

 *  This implementation uses a lazy version of Prim’s algorithm

 *  with a binary heap of edges.

 *  The constructor takes Θ(E log E) time in

 *  the worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(E) extra space in the worst case

 *  (not including the edge-weighted graph).

 *  

 *  For additional documentation,

 *  see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For alternate implementations, see {
@link
 PrimMST}, {
@link
 KruskalMST},

 *  and {
@link
 BoruvkaMST}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LazyPrimMST
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-12
;

    
private
 
double
 weight
;
       
// total weight of MST

    
private
 
Queue
< Edge >
 mst
;
     
// edges in the MST

    
private
 
boolean
[]
 marked
;
    
// marked[v] = true iff v on tree

    
private
 
MinPQ
< Edge >
 pq
;
      
// edges with one endpoint in tree

    
/**

     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.

     * 
@param
 G the edge-weighted graph

     */

    
public
 
LazyPrimMST
(
EdgeWeightedGraph
 G
)
 
{

        mst 
=
 
new
 
Queue
< Edge >
();

        pq 
=
 
new
 
MinPQ
< Edge >
();

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )       // run Prim from all vertices to              if   ( ! marked [ v ])  prim ( G ,  v );       // get a minimum spanning forest          // check optimality conditions          assert  check ( G );      }      // run Prim's algorithm      private   void  prim ( EdgeWeightedGraph  G ,   int  s )   {         scan ( G ,  s );          while   ( ! pq . isEmpty ())   {                          // better to stop when mst has V-1 edges              Edge  e  =  pq . delMin ();                        // smallest edge on pq              int  v  =  e . either (),  w  =  e . other ( v );          // two endpoints              assert  marked [ v ]   ||  marked [ w ];              if   ( marked [ v ]   &&  marked [ w ])   continue ;        // lazy, both v and w already scanned             mst . enqueue ( e );                              // add e to MST             weight  +=  e . weight ();              if   ( ! marked [ v ])  scan ( G ,  v );                 // v becomes part of tree              if   ( ! marked [ w ])  scan ( G ,  w );                 // w becomes part of tree          }      }      // add all edges e incident to v onto pq if the other endpoint has not yet been scanned      private   void  scan ( EdgeWeightedGraph  G ,   int  v )   {          assert   ! marked [ v ];         marked [ v ]   =   true ;          for   ( Edge  e  :  G . adj ( v ))              if   ( ! marked [ e . other ( v )])  pq . insert ( e );      }               /**      * Returns the edges in a minimum spanning tree (or forest).      *  @return  the edges in a minimum spanning tree (or forest) as      *    an iterable of edges      */      public   Iterable < Edge >
 edges
()
 
{

        
return
 mst
;

    
}

    
/**

     * Returns the sum of the edge weights in a minimum spanning tree (or forest).

     * 
@return
 the sum of the edge weights in a minimum spanning tree (or forest)

     */

    
public
 
double
 weight
()
 
{

        
return
 weight
;

    
}

    
// check optimality conditions (takes time proportional to E V lg* V)

    
private
 
boolean
 check
(
EdgeWeightedGraph
 G
)
 
{

        
// check weight

        
double
 totalWeight 
=
 
0.0
;

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            totalWeight 
+=
 e
.
weight
();

        
}

        
if
 
(
Math
.
abs
(
totalWeight 

 weight
())
 
>
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
printf
(
“Weight of edges does not equal weight(): %f vs. %f\n”
,
 totalWeight
,
 weight
());

            
return
 
false
;

        
}

        
// check that it is acyclic

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
==
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a forest”
);

                
return
 
false
;

            
}

            uf
.
union
(
v
,
 w
);

        
}

        
// check that it is a spanning forest

        
for
 
(
Edge
 e 
:
 G
.
edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
!=
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a spanning forest”
);

                
return
 
false
;

            
}

        
}

        
// check that it is a minimal spanning forest (cut optimality conditions)

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
// all edges in MST except e

            uf 
=
 
new
 UF
(
G
.
V
());

            
for
 
(
Edge
 f 
:
 mst
)
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(

!=
 e
)
 uf
.
union
(
x
,
 y
);

            
}

            
// check that e is min weight edge in crossing cut

            
for
 
(
Edge
 f 
:
 G
.
edges
())
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(
uf
.
find
(
x
)
 
!=
 uf
.
find
(
y
))
 
{

                    
if
 
(
f
.
weight
()
 
<  e . weight ())   {                          System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );                          return   false ;                      }                  }              }          }          return   true ;      }                /**      * Unit tests the { @code  LazyPrimMST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );          LazyPrimMST  mst  =   new   LazyPrimMST ( G );          for   ( Edge  e  :  mst . edges ())   {              StdOut . println ( e );          }          StdOut . printf ( "%.5f\n" ,  mst . weight ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/LinearProbingHashST.java edu/princeton/cs/algs4/LinearProbingHashST.java /******************************************************************************  *  Compilation:  javac LinearProbingHashST.java  *  Execution:    java LinearProbingHashST < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/34hash/tinyST.txt  *    *  Symbol-table implementation with linear-probing hash table.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  LinearProbingHashST} class represents a symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This implementation uses a linear probing hash table. It requires that

 *  the key type overrides the {
@code
 equals()} and {
@code
 hashCode()} methods.

 *  The expected time per putcontains, or remove

 *  operation is constant, subject to the uniform hashing assumption.

 *  The size, and is-empty operations take constant time.

 *  Construction takes constant time.

 *  

 *  For additional documentation, see Section 3.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For other implementations, see {
@link
 ST}, {
@link
 BinarySearchST},

 *  {
@link
 SequentialSearchST}, {
@link
 BST}, {
@link
 RedBlackBST}, and

 *  {
@link
 SeparateChainingHashST},

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinearProbingHashST
< Key ,   Value >
 
{

    
private
 
static
 
final
 
int
 INIT_CAPACITY 
=
 
4
;

    
private
 
int
 n
;
           
// number of key-value pairs in the symbol table

    
private
 
int
 m
;
           
// size of linear probing table

    
private
 
Key
[]
 keys
;
      
// the keys

    
private
 
Value
[]
 vals
;
    
// the values

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
LinearProbingHashST
()
 
{

        
this
(
INIT_CAPACITY
);

    
}

    
/**

     * Initializes an empty symbol table with the specified initial capacity.

     *

     * 
@param
 capacity the initial capacity

     */

    
public
 
LinearProbingHashST
(
int
 capacity
)
 
{

        m 
=
 capacity
;

        n 
=
 
0
;

        keys 
=
 
(
Key
[])
   
new
 
Object
[
m
];

        vals 
=
 
(
Value
[])
 
new
 
Object
[
m
];

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     *

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns true if this symbol table is empty.

     *

     * 
@return
 {
@code
 true} if this symbol table is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns true if this symbol table contains the specified key.

     *

     * 
@param
  key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key};

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
// hash function for keys – returns value between 0 and M-1

    
private
 
int
 hash
(
Key
 key
)
 
{

        
return
 
(
key
.
hashCode
()
 
&
 
0x7fffffff
)
 
%
 m
;

    
}

    
// resizes the hash table to the given capacity by re-hashing all of the keys

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
LinearProbingHashST
< Key ,   Value >
 temp 
=
 
new
 
LinearProbingHashST
< Key ,   Value >
(
capacity
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              if   ( keys [ i ]   !=   null )   {                 temp . put ( keys [ i ],  vals [ i ]);              }          }         keys  =  temp . keys ;         vals  =  temp . vals ;         m     =  temp . m ;      }      /**      * Inserts the specified key-value pair into the symbol table, overwriting the old       * value with the new value if the symbol table already contains the specified key.      * Deletes the specified key (and its associated value) from this symbol table      * if the specified value is { @code  null}.      *      *  @param   key the key      *  @param   val the value      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  put ( Key  key ,   Value  val )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );          if   ( val  ==   null )   {             delete ( key );              return ;          }          // double table size if 50% full          if   ( n  >=
 m
/
2
)
 resize
(
2
*
m
);

        
int
 i
;

        
for
 
(

=
 hash
(
key
);
 keys
[
i
]
 
!=
 
null
;
 i 
=
 
(

+
 
1
)
 
%
 m
)
 
{

            
if
 
(
keys
[
i
].
equals
(
key
))
 
{

                vals
[
i
]
 
=
 val
;

                
return
;

            
}

        
}

        keys
[
i
]
 
=
 key
;

        vals
[
i
]
 
=
 val
;

        n
++
;

    
}

    
/**

     * Returns the value associated with the specified key.

     * 
@param
 key the key

     * 
@return
 the value associated with {
@code
 key};

     *         {
@code
 null} if no such value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);

        
for
 
(
int
 i 
=
 hash
(
key
);
 keys
[
i
]
 
!=
 
null
;
 i 
=
 
(

+
 
1
)
 
%
 m
)

            
if
 
(
keys
[
i
].
equals
(
key
))

                
return
 vals
[
i
];

        
return
 
null
;

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).    

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to delete() is null”
);

        
if
 
(
!
contains
(
key
))
 
return
;

        
// find position i of key

        
int
 i 
=
 hash
(
key
);

        
while
 
(
!
key
.
equals
(
keys
[
i
]))
 
{

            i 
=
 
(

+
 
1
)
 
%
 m
;

        
}

        
// delete key and associated value

        keys
[
i
]
 
=
 
null
;

        vals
[
i
]
 
=
 
null
;

        
// rehash all keys in same cluster

        i 
=
 
(

+
 
1
)
 
%
 m
;

        
while
 
(
keys
[
i
]
 
!=
 
null
)
 
{

            
// delete keys[i] an vals[i] and reinsert

            
Key
   keyToRehash 
=
 keys
[
i
];

            
Value
 valToRehash 
=
 vals
[
i
];

            keys
[
i
]
 
=
 
null
;

            vals
[
i
]
 
=
 
null
;

            n

;

            put
(
keyToRehash
,
 valToRehash
);

            i 
=
 
(

+
 
1
)
 
%
 m
;

        
}

        n

;

        
// halves size of array if it’s 12.5% full or less

        
if
 
(

>
 
0
 
&&
 n 
<=  m / 8 )  resize ( m / 2 );          assert  check ();      }      /**      * Returns all keys in this symbol table as an { @code  Iterable}.      * To iterate over all of the keys in the symbol table named { @code  st},      * use the foreach notation: { @code  for (Key key : st.keys())}.      *      *  @return  all keys in this symbol table      */      public   Iterable < Key >
 keys
()
 
{

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )              if   ( keys [ i ]   !=   null )  queue . enqueue ( keys [ i ]);          return  queue ;      }      // integrity check - don't check after each put() because      // integrity not maintained during a delete()      private   boolean  check ()   {          // check that hash table is at most 50% full          if   ( m  <   2 * n )   {              System . err . println ( "Hash table size m = "   +  m  +   "; array size n = "   +  n );              return   false ;          }          // check that each key in table can be found by get()          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              if   ( keys [ i ]   ==   null )   continue ;              else   if   ( get ( keys [ i ])   !=  vals [ i ])   {                  System . err . println ( "get["   +  keys [ i ]   +   "] = "   +  get ( keys [ i ])   +   "; vals[i] = "   +  vals [ i ]);                  return   false ;              }          }          return   true ;      }      /**      * Unit tests the { @code  LinearProbingHashST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            LinearProbingHashST < String ,   Integer >
 st 
=
 
new
 
LinearProbingHashST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
// print keys

        
for
 
(
String
 s 
:
 st
.
keys
())
 

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));
 

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LinearProgramming.java
edu/princeton/cs/algs4/LinearProgramming.java
/******************************************************************************

 *  Compilation:  javac LinearProgramming.java

 *  Execution:    java LinearProgramming m n

 *  Dependencies: StdOut.java

 *

 *  Given an m-by-n matrix A, an m-length vector b, and an

 *  n-length vector c, solve the  LP { max cx : Ax <= b, x >= 0 }.

 *  Assumes that b >= 0 so that x = 0 is a basic feasible solution.

 *

 *  Creates an (m+1)-by-(n+m+1) simplex tableaux with the 

 *  RHS in column m+n, the objective function in row m, and

 *  slack variables in columns m through m+n-1.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 LinearProgramming} class represents a data type for solving a

 *  linear program of the form { max cx : Ax ≤ b, x ≥ 0 }, where A is a m-by-n

 *  matrix, b is an m-length vector, and c is an n-length vector. For simplicity,

 *  we assume that A is of full rank and that b ≥ 0 so that x = 0 is a basic

 *  feasible soution.

 *  

 *  The data type supplies methods for determining the optimal primal and

 *  dual solutions.

 *  

 *  This is a bare-bones implementation of the simplex algorithm.

 *  It uses Bland’s rule to determing the entering and leaving variables.

 *  It is not suitable for use on large inputs. It is also not robust

 *  in the presence of floating-point roundoff error.

 *  

 *  For additional documentation, see

 *  Section 6.5

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinearProgramming
 
{

    
private
 
static
 
final
 
double
 EPSILON 
=
 
1.0E-10
;

    
private
 
double
[][]
 a
;
   
// tableaux

    
private
 
int
 m
;
          
// number of constraints

    
private
 
int
 n
;
          
// number of original variables

    
private
 
int
[]
 basis
;
    
// basis[i] = basic variable corresponding to row i

                            
// only needed to print out solution, not book

    
/**

     * Determines an optimal solution to the linear program

     * { max cx : Ax ≤ b, x ≥ 0 }, where A is a m-by-n

     * matrix, b is an m-length vector, and c is an n-length vector.

     *

     * 
@param
  A the m-by-b matrix

     * 
@param
  b the m-length RHS vector

     * 
@param
  c the n-length cost vector

     * 
@throws
 IllegalArgumentException unless {
@code
 b[i] >= 0} for each {
@code
 i}

     * 
@throws
 ArithmeticException if the linear program is unbounded

     */
 

    
public
 
LinearProgramming
(
double
[][]
 A
,
 
double
[]
 b
,
 
double
[]
 c
)
 
{

        m 
=
 b
.
length
;

        n 
=
 c
.
length
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )              if   ( ! ( b [ i ]   >=
 
0
))
 
throw
 
new
 
IllegalArgumentException
(
“RHS must be nonnegative”
);

        a 
=
 
new
 
double
[
m
+
1
][
n
+
m
+
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 a [ i ][ j ]   =  A [ i ][ j ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             a [ i ][ n + i ]   =   1.0 ;          for   ( int  j  =   0 ;  j  <  n ;  j ++ )             a [ m ][ j ]   =  c [ j ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             a [ i ][ m + n ]   =  b [ i ];         basis  =   new   int [ m ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             basis [ i ]   =  n  +  i ;         solve ();          // check optimality conditions          assert  check ( A ,  b ,  c );      }      // run simplex algorithm starting from initial BFS      private   void  solve ()   {          while   ( true )   {              // find entering column q              int  q  =  bland ();              if   ( q  ==   - 1 )   break ;    // optimal              // find leaving row p              int  p  =  minRatioRule ( q );              if   ( p  ==   - 1 )   throw   new   ArithmeticException ( "Linear program is unbounded" );              // pivot             pivot ( p ,  q );              // update basis             basis [ p ]   =  q ;          }      }      // lowest index of a non-basic column with a positive cost      private   int  bland ()   {          for   ( int  j  =   0 ;  j  <  m + n ;  j ++ )              if   ( a [ m ][ j ]   >
 
0
)
 
return
 j
;

        
return
 

1
;
  
// optimal

    
}

   
// index of a non-basic column with most positive cost

    
private
 
int
 dantzig
()
 
{

        
int
 q 
=
 
0
;

        
for
 
(
int
 j 
=
 
1
;
 j 
<  m + n ;  j ++ )              if   ( a [ m ][ j ]   >
 a
[
m
][
q
])
 q 
=
 j
;

        
if
 
(
a
[
m
][
q
]
 
<=   0 )   return   - 1 ;    // optimal          else   return  q ;      }      // find row p using min ratio rule (-1 if no such row)      // (smallest such index if there is a tie)      private   int  minRatioRule ( int  q )   {          int  p  =   - 1 ;          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              // if (a[i][q] <= 0) continue;              if   ( a [ i ][ q ]   <=  EPSILON )   continue ;              else   if   ( p  ==   - 1 )  p  =  i ;              else   if   (( a [ i ][ m + n ]   /  a [ i ][ q ])   <   ( a [ p ][ m + n ]   /  a [ p ][ q ]))  p  =  i ;          }          return  p ;      }      // pivot on entry (p, q) using Gauss-Jordan elimination      private   void  pivot ( int  p ,   int  q )   {          // everything but row p and column q          for   ( int  i  =   0 ;  i  <=  m ;  i ++ )              for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )                  if   ( i  !=  p  &&  j  !=  q )  a [ i ][ j ]   -=  a [ p ][ j ]   *  a [ i ][ q ]   /  a [ p ][ q ];          // zero out column q          for   ( int  i  =   0 ;  i  <=  m ;  i ++ )              if   ( i  !=  p )  a [ i ][ q ]   =   0.0 ;          // scale row p          for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )              if   ( j  !=  q )  a [ p ][ j ]   /=  a [ p ][ q ];         a [ p ][ q ]   =   1.0 ;      }      /**      * Returns the optimal value of this linear program.      *      *  @return  the optimal value of this linear program      *      */      public   double  value ()   {          return   - a [ m ][ m + n ];      }      /**      * Returns the optimal primal solution to this linear program.      *      *  @return  the optimal primal solution to this linear program      */      public   double []  primal ()   {          double []  x  =   new   double [ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )              if   ( basis [ i ]   <  n )  x [ basis [ i ]]   =  a [ i ][ m + n ];          return  x ;      }      /**      * Returns the optimal dual solution to this linear program      *      *  @return  the optimal dual solution to this linear program      */      public   double []  dual ()   {          double []  y  =   new   double [ m ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             y [ i ]   =   - a [ m ][ n + i ];          return  y ;      }      // is the solution primal feasible?      private   boolean  isPrimalFeasible ( double [][]  A ,   double []  b )   {          double []  x  =  primal ();          // check that x >= 0

        
for
 
(
int
 j 
=
 
0
;
 j 
<  x . length ;  j ++ )   {              if   ( x [ j ]   <   0.0 )   {                  StdOut . println ( "x["   +  j  +   "] = "   +  x [ j ]   +   " is negative" );                  return   false ;              }          }          // check that Ax <= b          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              double  sum  =   0.0 ;              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 sum  +=  A [ i ][ j ]   *  x [ j ];              }              if   ( sum  >
 b
[
i
]
 
+
 EPSILON
)
 
{

                
StdOut
.
println
(
“not primal feasible”
);

                
StdOut
.
println
(
“b[”
 
+
 i 
+
 
“] = ”
 
+
 b
[
i
]
 
+
 
“, sum = ”
 
+
 sum
);

                
return
 
false
;

            
}

        
}

        
return
 
true
;

    
}

    
// is the solution dual feasible?

    
private
 
boolean
 isDualFeasible
(
double
[][]
 A
,
 
double
[]
 c
)
 
{

        
double
[]
 y 
=
 dual
();

        
// check that y >= 0

        
for
 
(
int
 i 
=
 
0
;
 i 
<  y . length ;  i ++ )   {              if   ( y [ i ]   <   0.0 )   {                  StdOut . println ( "y["   +  i  +   "] = "   +  y [ i ]   +   " is negative" );                  return   false ;              }          }          // check that yA >= c

        
for
 
(
int
 j 
=
 
0
;
 j 
<  n ;  j ++ )   {              double  sum  =   0.0 ;              for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {                 sum  +=  A [ i ][ j ]   *  y [ i ];              }              if   ( sum  <  c [ j ]   -  EPSILON )   {                  StdOut . println ( "not dual feasible" );                  StdOut . println ( "c["   +  j  +   "] = "   +  c [ j ]   +   ", sum = "   +  sum );                  return   false ;              }          }          return   true ;      }      // check that optimal value = cx = yb      private   boolean  isOptimal ( double []  b ,   double []  c )   {          double []  x  =  primal ();          double []  y  =  dual ();          double  value  =  value ();          // check that value = cx = yb          double  value1  =   0.0 ;          for   ( int  j  =   0 ;  j  <  x . length ;  j ++ )             value1  +=  c [ j ]   *  x [ j ];          double  value2  =   0.0 ;          for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )             value2  +=  y [ i ]   *  b [ i ];          if   ( Math . abs ( value  -  value1 )   >
 EPSILON 
||
 
Math
.
abs
(
value 

 value2
)
 
>
 EPSILON
)
 
{

            
StdOut
.
println
(
“value = ”
 
+
 value 
+
 
“, cx = ”
 
+
 value1 
+
 
“, yb = ”
 
+
 value2
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
private
 
boolean
 check
(
double
[][]
A
,
 
double
[]
 b
,
 
double
[]
 c
)
 
{

        
return
 isPrimalFeasible
(
A
,
 b
)
 
&&
 isDualFeasible
(
A
,
 c
)
 
&&
 isOptimal
(
b
,
 c
);

    
}

    
// print tableaux

    
private
 
void
 show
()
 
{

        
StdOut
.
println
(
“m = ”
 
+
 m
);

        
StdOut
.
println
(
“n = ”
 
+
 n
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<=  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )   {                  StdOut . printf ( "%7.2f " ,  a [ i ][ j ]);                  // StdOut.printf("%10.7f ", a[i][j]);              }              StdOut . println ();          }          StdOut . println ( "value = "   +  value ());          for   ( int  i  =   0 ;  i  <  m ;  i ++ )              if   ( basis [ i ]   <  n )   StdOut . println ( "x_"   +  basis [ i ]   +   " = "   +  a [ i ][ m + n ]);          StdOut . println ();      }      private   static   void  test ( double [][]  A ,   double []  b ,   double []  c )   {          LinearProgramming  lp ;          try   {             lp  =   new   LinearProgramming ( A ,  b ,  c );          }          catch   ( ArithmeticException  e )   {              System . out . println ( e );              return ;          }          StdOut . println ( "value = "   +  lp . value ());          double []  x  =  lp . primal ();          for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )              StdOut . println ( "x["   +  i  +   "] = "   +  x [ i ]);          double []  y  =  lp . dual ();          for   ( int  j  =   0 ;  j  <  y . length ;  j ++ )              StdOut . println ( "y["   +  j  +   "] = "   +  y [ j ]);      }      private   static   void  test1 ()   {          double [][]  A  =   {              {   - 1 ,    1 ,    0   },              {    1 ,    4 ,    0   },              {    2 ,    1 ,    0   },              {    3 ,   - 4 ,    0   },              {    0 ,    0 ,    1   },          };          double []  c  =   {   1 ,   1 ,   1   };          double []  b  =   {   5 ,   45 ,   27 ,   24 ,   4   };         test ( A ,  b ,  c );      }      // x0 = 12, x1 = 28, opt = 800      private   static   void  test2 ()   {          double []  c  =   {    13.0 ,    23.0   };          double []  b  =   {   480.0 ,   160.0 ,   1190.0   };          double [][]  A  =   {              {    5.0 ,   15.0   },              {    4.0 ,    4.0   },              {   35.0 ,   20.0   },          };         test ( A ,  b ,  c );      }      // unbounded      private   static   void  test3 ()   {          double []  c  =   {   2.0 ,   3.0 ,   - 1.0 ,   - 12.0   };          double []  b  =   {    3.0 ,     2.0   };          double [][]  A  =   {              {   - 2.0 ,   - 9.0 ,    1.0 ,    9.0   },              {    1.0 ,    1.0 ,   - 1.0 ,   - 2.0   },          };         test ( A ,  b ,  c );      }      // degenerate - cycles if you choose most positive objective function coefficient      private   static   void  test4 ()   {          double []  c  =   {   10.0 ,   - 57.0 ,   - 9.0 ,   - 24.0   };          double []  b  =   {    0.0 ,     0.0 ,    1.0   };          double [][]  A  =   {              {   0.5 ,   - 5.5 ,   - 2.5 ,   9.0   },              {   0.5 ,   - 1.5 ,   - 0.5 ,   1.0   },              {   1.0 ,    0.0 ,    0.0 ,   0.0   },          };         test ( A ,  b ,  c );      }      /**      * Unit tests the { @code  LinearProgramming} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          StdOut . println ( "----- test 1 --------------------" );         test1 ();          StdOut . println ();          StdOut . println ( "----- test 2 --------------------" );         test2 ();          StdOut . println ();          StdOut . println ( "----- test 3 --------------------" );         test3 ();          StdOut . println ();          StdOut . println ( "----- test 4 --------------------" );         test4 ();          StdOut . println ();          StdOut . println ( "----- test random ---------------" );          int  m  =   Integer . parseInt ( args [ 0 ]);          int  n  =   Integer . parseInt ( args [ 1 ]);          double []  c  =   new   double [ n ];          double []  b  =   new   double [ m ];          double [][]  A  =   new   double [ m ][ n ];          for   ( int  j  =   0 ;  j  <  n ;  j ++ )             c [ j ]   =   StdRandom . uniform ( 1000 );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )             b [ i ]   =   StdRandom . uniform ( 1000 );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 A [ i ][ j ]   =   StdRandom . uniform ( 100 );          LinearProgramming  lp  =   new   LinearProgramming ( A ,  b ,  c );         test ( A ,  b ,  c );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/LinearRegression.java edu/princeton/cs/algs4/LinearRegression.java /******************************************************************************  *  Compilation:  javac LinearRegression.java  *  Execution:    java  LinearRegression  *  Dependencies: none  *    *  Compute least squares solution to y = beta * x + alpha.  *  Simple linear regression.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  LinearRegression} class performs a simple linear regression  *  on an set of n data points (yixi).

 *  That is, it fits a straight line y = α + β x,

 *  (where y is the response variable, x is the predictor variable,

 *  α is the y-intercept, and β is the slope)

 *  that minimizes the sum of squared residuals of the linear regression model.

 *  It also computes associated statistics, including the coefficient of

 *  determination R2 and the standard deviation of the

 *  estimates for the slope and y-intercept.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinearRegression
 
{

    
private
 
final
 
double
 intercept
,
 slope
;

    
private
 
final
 
double
 r2
;

    
private
 
final
 
double
 svar0
,
 svar1
;

   
/**

     * Performs a linear regression on the data points {
@code
 (y[i], x[i])}.

     *

     * 
@param
  x the values of the predictor variable

     * 
@param
  y the corresponding values of the response variable

     * 
@throws
 IllegalArgumentException if the lengths of the two arrays are not equal

     */

    
public
 
LinearRegression
(
double
[]
 x
,
 
double
[]
 y
)
 
{

        
if
 
(
x
.
length 
!=
 y
.
length
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“array lengths are not equal”
);

        
}

        
int
 n 
=
 x
.
length
;

        
// first pass

        
double
 sumx 
=
 
0.0
,
 sumy 
=
 
0.0
,
 sumx2 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             sumx   +=  x [ i ];             sumx2  +=  x [ i ] * x [ i ];             sumy   +=  y [ i ];          }          double  xbar  =  sumx  /  n ;          double  ybar  =  sumy  /  n ;          // second pass: compute summary statistics          double  xxbar  =   0.0 ,  yybar  =   0.0 ,  xybar  =   0.0 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             xxbar  +=   ( x [ i ]   -  xbar )   *   ( x [ i ]   -  xbar );             yybar  +=   ( y [ i ]   -  ybar )   *   ( y [ i ]   -  ybar );             xybar  +=   ( x [ i ]   -  xbar )   *   ( y [ i ]   -  ybar );          }         slope   =  xybar  /  xxbar ;         intercept  =  ybar  -  slope  *  xbar ;          // more statistical analysis          double  rss  =   0.0 ;        // residual sum of squares          double  ssr  =   0.0 ;        // regression sum of squares          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              double  fit  =  slope * x [ i ]   +  intercept ;             rss  +=   ( fit  -  y [ i ])   *   ( fit  -  y [ i ]);             ssr  +=   ( fit  -  ybar )   *   ( fit  -  ybar );          }          int  degreesOfFreedom  =  n - 2 ;         r2     =  ssr  /  yybar ;          double  svar   =  rss  /  degreesOfFreedom ;         svar1  =  svar  /  xxbar ;         svar0  =  svar / n  +  xbar * xbar * svar1 ;      }     /**      * Returns the y-intercept α of the best of the best-fit line y = α + β x.

     *

     * 
@return
 the y-intercept α of the best-fit line y = α + β x

     */

    
public
 
double
 intercept
()
 
{

        
return
 intercept
;

    
}

   
/**

     * Returns the slope β of the best of the best-fit line y = α + β x.

     *

     * 
@return
 the slope β of the best-fit line y = α + β x

     */

    
public
 
double
 slope
()
 
{

        
return
 slope
;

    
}

   
/**

     * Returns the coefficient of determination R2.

     *

     * 
@return
 the coefficient of determination R2,

     *         which is a real number between 0 and 1

     */

    
public
 
double
 R2
()
 
{

        
return
 r2
;

    
}

   
/**

     * Returns the standard error of the estimate for the intercept.

     *

     * 
@return
 the standard error of the estimate for the intercept

     */

    
public
 
double
 interceptStdErr
()
 
{

        
return
 
Math
.
sqrt
(
svar0
);

    
}

   
/**

     * Returns the standard error of the estimate for the slope.

     *

     * 
@return
 the standard error of the estimate for the slope

     */

    
public
 
double
 slopeStdErr
()
 
{

        
return
 
Math
.
sqrt
(
svar1
);

    
}

   
/**

     * Returns the expected response {
@code
 y} given the value of the predictor

     * variable {
@code
 x}.

     *

     * 
@param
  x the value of the predictor variable

     * 
@return
 the expected response {
@code
 y} given the value of the predictor

     *         variable {
@code
 x}

     */

    
public
 
double
 predict
(
double
 x
)
 
{

        
return
 slope
*

+
 intercept
;

    
}

   
/**

     * Returns a string representation of the simple linear regression model.

     *

     * 
@return
 a string representation of the simple linear regression model,

     *         including the best-fit line and the coefficient of determination

     *         R2

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        s
.
append
(
String
.
format
(
“%.2f n + %.2f”
,
 slope
(),
 intercept
()));

        s
.
append
(
”  (R^2 = ”
 
+
 
String
.
format
(
“%.3f”
,
 R2
())
 
+
 
“)”
);

        
return
 s
.
toString
();

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LinkedBag.java
edu/princeton/cs/algs4/LinkedBag.java
/******************************************************************************

 *  Compilation:  javac LinkedBag.java

 *  Execution:    java LinkedBag < input.txt  *  Dependencies: StdIn.java StdOut.java  *  *  A generic bag or multiset, implemented using a singly linked list.  *  *  % more tobe.txt   *  to be or not to - be - - that - - - is  *  *  % java LinkedBag < tobe.txt  *  size of bag = 14  *  is  *  -  *  -  *  -  *  that  *  -  *  -  *  be  *  -  *  to  *  not  *  or  *  be  *  to  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  LinkedBag} class represents a bag (or multiset) of   *  generic items. It supports insertion and iterating over the   *  items in arbitrary order.  *  

 *  This implementation uses a singly linked list with a non-static nested class Node.

 *  See {
@link
 Bag} for a version that uses a static nested class.

 *  The addisEmpty, and size operations

 *  take constant time. Iteration takes time proportional to the number of items.

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinkedBag
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Node
 first
;
    
// beginning of bag

    
private
 
int
 n
;
         
// number of elements in bag

    
// helper linked list class

    
private
 
class
 
Node
 
{

        
private
 
Item
 item
;

        
private
 
Node
 next
;

    
}

    
/**

     * Initializes an empty bag.

     */

    
public
 
LinkedBag
()
 
{

        first 
=
 
null
;

        n 
=
 
0
;

    
}

    
/**

     * Is this bag empty?

     * 
@return
 true if this bag is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in this bag.

     * 
@return
 the number of items in this bag

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Adds the item to this bag.

     * 
@param
 item the item to add to this bag

     */

    
public
 
void
 add
(
Item
 item
)
 
{

        
Node
 oldfirst 
=
 first
;

        first 
=
 
new
 
Node
();

        first
.
item 
=
 item
;

        first
.
next 
=
 oldfirst
;

        n
++
;

    
}

    
/**

     * Returns an iterator that iterates over the items in the bag.

     */

    
public
 
Iterator
< Item >
 iterator
()
  
{

        
return
 
new
 
ListIterator
();
  

    
}

    
// an iterator over a linked list

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
 current
;

        
// creates a new iterator

        
public
 
ListIterator
()
 
{

            current 
=
 first
;

        
}

        
// is there a next item in the iterator?

        
public
 
boolean
 hasNext
()
 
{

            
return
 current 
!=
 
null
;

        
}

        
// this method is optional in Iterator interface

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

        
// returns the next item in the iterator (and advances the iterator)

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 LinkedBag} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
LinkedBag
< String >
 bag 
=
 
new
 
LinkedBag
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            bag
.
add
(
item
);

        
}

        
StdOut
.
println
(
“size of bag = ”
 
+
 bag
.
size
());

        
for
 
(
String
 s 
:
 bag
)
 
{

            
StdOut
.
println
(
s
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LinkedQueue.java
edu/princeton/cs/algs4/LinkedQueue.java
/******************************************************************************

 *  Compilation:  javac LinkedQueue.java

 *  Execution:    java LinkedQueue < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt    *  *  A generic queue, implemented using a singly linked list.  *  *  % java Queue < tobe.txt   *  to be or not to be (2 left on queue)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  LinkedQueue} class represents a first-in-first-out (FIFO)  *  queue of generic items.  *  It supports the usual enqueue and dequeue

 *  operations, along with methods for peeking at the first item,

 *  testing if the queue is empty, and iterating through

 *  the items in FIFO order.

 *  

 *  This implementation uses a singly linked list with a non-static nested class 

 *  for linked-list nodes.  See {
@link
 Queue} for a version that uses a static nested class.

 *  The enqueuedequeuepeeksize, and is-empty

 *  operations all take constant time in the worst case.

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinkedQueue
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
int
 n
;
         
// number of elements on queue

    
private
 
Node
 first
;
    
// beginning of queue

    
private
 
Node
 last
;
     
// end of queue

    
// helper linked list class

    
private
 
class
 
Node
 
{

        
private
 
Item
 item
;

        
private
 
Node
 next
;

    
}

    
/**

     * Initializes an empty queue.

     */

    
public
 
LinkedQueue
()
 
{

        first 
=
 
null
;

        last  
=
 
null
;

        n 
=
 
0
;

        
assert
 check
();

    
}

    
/**

     * Is this queue empty?

     * 
@return
 true if this queue is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in this queue.

     * 
@return
 the number of items in this queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;
     

    
}

    
/**

     * Returns the item least recently added to this queue.

     * 
@return
 the item least recently added to this queue

     * 
@throws
 java.util.NoSuchElementException if this queue is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Queue underflow”
);

        
return
 first
.
item
;

    
}

    
/**

     * Adds the item to this queue.

     * 
@param
 item the item to add

     */

    
public
 
void
 enqueue
(
Item
 item
)
 
{

        
Node
 oldlast 
=
 last
;

        last 
=
 
new
 
Node
();

        last
.
item 
=
 item
;

        last
.
next 
=
 
null
;

        
if
 
(
isEmpty
())
 first 
=
 last
;

        
else
           oldlast
.
next 
=
 last
;

        n
++
;

        
assert
 check
();

    
}

    
/**

     * Removes and returns the item on this queue that was least recently added.

     * 
@return
 the item on this queue that was least recently added

     * 
@throws
 java.util.NoSuchElementException if this queue is empty

     */

    
public
 
Item
 dequeue
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Queue underflow”
);

        
Item
 item 
=
 first
.
item
;

        first 
=
 first
.
next
;

        n

;

        
if
 
(
isEmpty
())
 last 
=
 
null
;
   
// to avoid loitering

        
assert
 check
();

        
return
 item
;

    
}

    
/**

     * Returns a string representation of this queue.

     * 
@return
 the sequence of items in FIFO order, separated by spaces

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        
for
 
(
Item
 item 
:
 
this
)

            s
.
append
(
item 
+
 
” ”
);

        
return
 s
.
toString
();

    
}
 

    
// check internal invariants

    
private
 
boolean
 check
()
 
{

        
if
 
(

<   0 )   {              return   false ;          }          else   if   ( n  ==   0 )   {              if   ( first  !=   null )   return   false ;              if   ( last   !=   null )   return   false ;          }          else   if   ( n  ==   1 )   {              if   ( first  ==   null   ||  last  ==   null )   return   false ;              if   ( first  !=  last )                   return   false ;              if   ( first . next  !=   null )              return   false ;          }          else   {              if   ( first  ==   null   ||  last  ==   null )   return   false ;              if   ( first  ==  last )        return   false ;              if   ( first . next  ==   null )   return   false ;              if   ( last . next   !=   null )   return   false ;              // check internal consistency of instance variable n              int  numberOfNodes  =   0 ;              for   ( Node  x  =  first ;  x  !=   null   &&  numberOfNodes  <=  n ;  x  =  x . next )   {                 numberOfNodes ++ ;              }              if   ( numberOfNodes  !=  n )   return   false ;              // check internal consistency of instance variable last              Node  lastNode  =  first ;              while   ( lastNode . next  !=   null )   {                 lastNode  =  lastNode . next ;              }              if   ( last  !=  lastNode )   return   false ;          }          return   true ;      }          /**      * Returns an iterator that iterates over the items in this queue in FIFO order.      *  @return  an iterator that iterates over the items in this queue in FIFO order      */      public   Iterator < Item >
 iterator
()
  
{

        
return
 
new
 
ListIterator
();
  

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
 current 
=
 first
;

        
public
 
boolean
 hasNext
()
  
{
 
return
 current 
!=
 
null
;
                     
}

        
public
 
void
 remove
()
      
{
 
throw
 
new
 
UnsupportedOperationException
();
  
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 LinkedQueue} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
LinkedQueue
< String >
 queue 
=
 
new
 
LinkedQueue
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))

                queue
.
enqueue
(
item
);

            
else
 
if
 
(
!
queue
.
isEmpty
())

                
StdOut
.
print
(
queue
.
dequeue
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 queue
.
size
()
 
+
 
” left on queue)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LinkedStack.java
edu/princeton/cs/algs4/LinkedStack.java
/******************************************************************************

 *  Compilation:  javac LinkedStack.java

 *  Execution:    java LinkedStack < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  *  *  A generic stack, implemented using a linked list. Each stack  *  element is of type Item.  *    *  % more tobe.txt   *  to be or not to - be - - that - - - is  *  *  % java LinkedStack < tobe.txt  *  to be not that or be (2 left on stack)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  LinkedStack} class represents a last-in-first-out (LIFO) stack of  *  generic items.  *  It supports the usual push and pop operations, along with methods

 *  for peeking at the top item, testing if the stack is empty, and iterating through

 *  the items in LIFO order.

 *  

 *  This implementation uses a singly linked list with a non-static nested class for 

 *  linked-list nodes. See {
@link
 Stack} for a version that uses a static nested class.

 *  The pushpoppeeksize, and is-empty

 *  operations all take constant time in the worst case.

 *  

 *  For additional documentation,

 *  see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LinkedStack
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
int
 n
;
          
// size of the stack

    
private
 
Node
 first
;
     
// top of stack

    
// helper linked list class

    
private
 
class
 
Node
 
{

        
private
 
Item
 item
;

        
private
 
Node
 next
;

    
}

    
/**

     * Initializes an empty stack.

     */

    
public
 
LinkedStack
()
 
{

        first 
=
 
null
;

        n 
=
 
0
;

        
assert
 check
();

    
}

    
/**

     * Is this stack empty?

     * 
@return
 true if this stack is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in the stack.

     * 
@return
 the number of items in the stack

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Adds the item to this stack.

     * 
@param
 item the item to add

     */

    
public
 
void
 push
(
Item
 item
)
 
{

        
Node
 oldfirst 
=
 first
;

        first 
=
 
new
 
Node
();

        first
.
item 
=
 item
;

        first
.
next 
=
 oldfirst
;

        n
++
;

        
assert
 check
();

    
}

    
/**

     * Removes and returns the item most recently added to this stack.

     * 
@return
 the item most recently added

     * 
@throws
 java.util.NoSuchElementException if this stack is empty

     */

    
public
 
Item
 pop
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Stack underflow”
);

        
Item
 item 
=
 first
.
item
;
        
// save item to return

        first 
=
 first
.
next
;
            
// delete first node

        n

;

        
assert
 check
();

        
return
 item
;
                   
// return the saved item

    
}

    
/**

     * Returns (but does not remove) the item most recently added to this stack.

     * 
@return
 the item most recently added to this stack

     * 
@throws
 java.util.NoSuchElementException if this stack is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Stack underflow”
);

        
return
 first
.
item
;

    
}

    
/**

     * Returns a string representation of this stack.

     * 
@return
 the sequence of items in the stack in LIFO order, separated by spaces

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        
for
 
(
Item
 item 
:
 
this
)

            s
.
append
(
item 
+
 
” ”
);

        
return
 s
.
toString
();

    
}

       

    
/**

     * Returns an iterator to this stack that iterates through the items in LIFO order.

     * 
@return
 an iterator to this stack that iterates through the items in LIFO order.

     */

    
public
 
Iterator
< Item >
 iterator
()
 
{

        
return
 
new
 
ListIterator
();

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
 current 
=
 first
;

        
public
 
boolean
 hasNext
()
  
{
 
return
 current 
!=
 
null
;
                     
}

        
public
 
void
 remove
()
      
{
 
throw
 
new
 
UnsupportedOperationException
();
  
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
// check internal invariants

    
private
 
boolean
 check
()
 
{

        
// check a few properties of instance variable ‘first’

        
if
 
(

<   0 )   {              return   false ;          }          if   ( n  ==   0 )   {              if   ( first  !=   null )   return   false ;          }          else   if   ( n  ==   1 )   {              if   ( first  ==   null )        return   false ;              if   ( first . next  !=   null )   return   false ;          }          else   {              if   ( first  ==   null )        return   false ;              if   ( first . next  ==   null )   return   false ;          }          // check internal consistency of instance variable n          int  numberOfNodes  =   0 ;          for   ( Node  x  =  first ;  x  !=   null   &&  numberOfNodes  <=  n ;  x  =  x . next )   {             numberOfNodes ++ ;          }          if   ( numberOfNodes  !=  n )   return   false ;          return   true ;      }      /**      * Unit tests the { @code  LinkedStack} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          LinkedStack < String >
 stack 
=
 
new
 
LinkedStack
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))

                stack
.
push
(
item
);

            
else
 
if
 
(
!
stack
.
isEmpty
())

                
StdOut
.
print
(
stack
.
pop
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 stack
.
size
()
 
+
 
” left on stack)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LongestCommonSubstring.java
edu/princeton/cs/algs4/LongestCommonSubstring.java
/******************************************************************************

 *  Compilation:  javac LongestCommonSubstring.java

 *  Execution:    java  LongestCommonSubstring file1.txt file2.txt

 *  Dependencies: SuffixArray.java In.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt

 *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt

 *  

 *  Read in two text files and find the longest substring that

 *  appears in both texts.

 * 

 *  % java LongestCommonSubstring tale.txt mobydick.txt

 *  ‘ seemed on the point of being ‘

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 LongestCommonSubstring} class provides a {
@link
 SuffixArray}

 *  client for computing the longest common substring that appears in two

 *  given strings.

 *  

 *  This implementation computes the suffix array of each string and applies a

 *  merging operation to determine the longest common substring.

 *  For an alternate implementation, see

 *  LongestCommonSubstringConcatenate.java.

 *  

 *  For additional documentation,

 *  see Section 6.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *     

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LongestCommonSubstring
 
{

    
// Do not instantiate.

    
private
 
LongestCommonSubstring
()
 
{
 
}

    
// return the longest common prefix of suffix s[p..] and suffix t[q..]

    
private
 
static
 
String
 lcp
(
String
 s
,
 
int
 p
,
 
String
 t
,
 
int
 q
)
 
{

        
int
 n 
=
 
Math
.
min
(
s
.
length
()
 

 p
,
 t
.
length
()
 

 q
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   ( s . charAt ( p  +  i )   !=  t . charAt ( q  +  i ))                  return  s . substring ( p ,  p  +  i );          }          return  s . substring ( p ,  p  +  n );      }      // compare suffix s[p..] and suffix t[q..]      private   static   int  compare ( String  s ,   int  p ,   String  t ,   int  q )   {          int  n  =   Math . min ( s . length ()   -  p ,  t . length ()   -  q );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( s . charAt ( p  +  i )   !=  t . charAt ( q  +  i ))                  return  s . charAt ( p + i )   -  t . charAt ( q + i );          }          if        ( s . length ()   -  p  <  t . length ()   -  q )   return   - 1 ;          else   if   ( s . length ()   -  p  >
 t
.
length
()
 

 q
)
 
return
 
+
1
;

        
else
                                      
return
  
0
;

    
}

    
/**

     * Returns the longest common string of the two specified strings.

     *

     * 
@param
  s one string

     * 
@param
  t the other string

     * 
@return
 the longest common string that appears as a substring

     *         in both {
@code
 s} and {
@code
 t}; the empty string

     *         if no such string

     */

    
public
 
static
 
String
 lcs
(
String
 s
,
 
String
 t
)
 
{

        
SuffixArray
 suffix1 
=
 
new
 
SuffixArray
(
s
);

        
SuffixArray
 suffix2 
=
 
new
 
SuffixArray
(
t
);

        
// find longest common substring by “merging” sorted suffixes 

        
String
 lcs 
=
 
“”
;

        
int
 i 
=
 
0
,
 j 
=
 
0
;

        
while
 
(

<  s . length ()   &&  j  <  t . length ())   {              int  p  =  suffix1 . index ( i );              int  q  =  suffix2 . index ( j );              String  x  =  lcp ( s ,  p ,  t ,  q );              if   ( x . length ()   >
 lcs
.
length
())
 lcs 
=
 x
;

            
if
 
(
compare
(
s
,
 p
,
 t
,
 q
)
 
<   0 )  i ++ ;              else                          j ++ ;          }          return  lcs ;      }      /**      * Unit tests the { @code  lcs()} method.      * Reads in two strings from files specified as command-line arguments;      * computes the longest common substring; and prints the results to      * standard output.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in1  =   new   In ( args [ 0 ]);          In  in2  =   new   In ( args [ 1 ]);          String  s  =  in1 . readAll (). trim (). replaceAll ( "\\s+" ,   " " );          String  t  =  in2 . readAll (). trim (). replaceAll ( "\\s+" ,   " " );          StdOut . println ( "'"   +  lcs ( s ,  t )   +   "'" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/LongestRepeatedSubstring.java edu/princeton/cs/algs4/LongestRepeatedSubstring.java /******************************************************************************  *  Compilation:  javac LongestRepeatedSubstring.java  *  Execution:    java LongestRepeatedSubstring < file.txt  *  Dependencies: StdIn.java SuffixArray.java  *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt  *                https://algs4.cs.princeton.edu/63suffix/tinyTale.txt  *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt  *    *  Reads a text string from stdin, replaces all consecutive blocks of  *  whitespace with a single space, and then computes the longest  *  repeated substring in that text using a suffix array.  *   *  % java LongestRepeatedSubstring < tinyTale.txt   *  'st of times it was the '  *  *  % java LongestRepeatedSubstring < mobydick.txt  *  ',- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! Th'  *   *  % java LongestRepeatedSubstring  *  aaaaaaaaa  *  'aaaaaaaa'  *  *  % java LongestRepeatedSubstring  *  abcdefg  *  ''  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  LongestRepeatedSubstring} class provides a { @link  SuffixArray}  *  client for computing the longest repeated substring of a string that  *  appears at least twice. The repeated substrings may overlap (but must  *  be distinct).  *  

 *  For additional documentation,

 *  see Section 6.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  See also {
@link
 LongestCommonSubstring}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LongestRepeatedSubstring
 
{

    
// Do not instantiate.

    
private
 
LongestRepeatedSubstring
()
 
{
 
}

    
/**

     * Returns the longest common string of the two specified strings.

     *

     * 
@param
  s one string

     * 
@param
  t the other string

     * 
@return
 the longest common string that appears as a substring

     */

    
/**

     * Returns the longest repeated substring of the specified string.

     *

     * 
@param
  text the string

     * 
@return
 the longest repeated substring that appears in {
@code
 text};

     *         the empty string if no such string

     */

    
public
 
static
 
String
 lrs
(
String
 text
)
 
{

        
int
 n 
=
 text
.
length
();

        
SuffixArray
 sa 
=
 
new
 
SuffixArray
(
text
);

        
String
 lrs 
=
 
“”
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              int  length  =  sa . lcp ( i );              if   ( length  >
 lrs
.
length
())
 
{

                
// lrs = sa.select(i).substring(0, length);

                lrs 
=
 text
.
substring
(
sa
.
index
(
i
),
 sa
.
index
(
i
)
 
+
 length
);

            
}

        
}

        
return
 lrs
;

    
}

    
/**

     * Unit tests the {
@code
 lrs()} method.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 text 
=
 
StdIn
.
readAll
().
replaceAll
(
“\\s+”
,
 
” ”
);

        
StdOut
.
println
(
“‘”
 
+
 lrs
(
text
)
 
+
 
“‘”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LookupCSV.java
edu/princeton/cs/algs4/LookupCSV.java
/******************************************************************************

 *  Compilation:  javac LookupCSV.java

 *  Execution:    java LookupCSV file.csv keyField valField

 *  Dependencies: ST.java In.java StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/35applications/DJIA.csv

 *                https://algs4.cs.princeton.edu/35applications/UPC.csv

 *                https://algs4.cs.princeton.edu/35applications/amino.csv

 *                https://algs4.cs.princeton.edu/35applications/elements.csv

 *                https://algs4.cs.princeton.edu/35applications/ip.csv

 *                https://algs4.cs.princeton.edu/35applications/morse.csv

 *  

 *  Reads in a set of key-value pairs from a two-column CSV file

 *  specified on the command line; then, reads in keys from standard

 *  input and prints out corresponding values.

 * 

 *  % java LookupCSV amino.csv 0 3     % java LookupCSV ip.csv 0 1 

 *  TTA                                www.google.com 

 *  Leucine                            216.239.41.99 

 *  ABC                               

 *  Not found                          % java LookupCSV ip.csv 1 0 

 *  TCT                                216.239.41.99 

 *  Serine                             www.google.com 

 *                                 

 *  % java LookupCSV amino.csv 3 0     % java LookupCSV DJIA.csv 0 1 

 *  Glycine                            29-Oct-29 

 *  GGG                                252.38 

 *                                     20-Oct-87 

 *                                     1738.74

 *

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 LookupCSV} class provides a data-driven client for reading in a

 *  key-value pairs from a file; then, printing the values corresponding to the

 *  keys found on standard input. Both keys and values are strings.

 *  The fields to serve as the key and value are taken as command-line arguments.

 *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LookupCSV
 
{

    
// Do not instantiate.

    
private
 
LookupCSV
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 keyField 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 valField 
=
 
Integer
.
parseInt
(
args
[
2
]);

        
// symbol table

        ST
< String ,   String >
 st 
=
 
new
 ST
< String ,   String >
();

        
// read in the data from csv file

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
while
 
(
in
.
hasNextLine
())
 
{

            
String
 line 
=
 in
.
readLine
();

            
String
[]
 tokens 
=
 line
.
split
(
“,”
);

            
String
 key 
=
 tokens
[
keyField
];

            
String
 val 
=
 tokens
[
valField
];

            st
.
put
(
key
,
 val
);

        
}

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 s 
=
 
StdIn
.
readString
();

            
if
 
(
st
.
contains
(
s
))
 
StdOut
.
println
(
st
.
get
(
s
));

            
else
                
StdOut
.
println
(
“Not found”
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LookupIndex.java
edu/princeton/cs/algs4/LookupIndex.java
/******************************************************************************

 *  Compilation:  javac LookupIndex.java

 *  Execution:    java LookupIndex movies.txt “/”

 *  Dependencies: ST.java Queue.java In.java StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/35applications/aminoI.csv

 *                https://algs4.cs.princeton.edu/35applications/movies.txt

 *

 *  % java LookupIndex aminoI.csv “,”

 *  Serine

 *    TCT

 *    TCA

 *    TCG

 *    AGT

 *    AGC

 *  TCG

 *    Serine

 *

 *  % java LookupIndex movies.txt “/”

 *  Bacon, Kevin

 *    Animal House (1978)

 *    Apollo 13 (1995)

 *    Beauty Shop (2005)

 *    Diner (1982)

 *    Few Good Men, A (1992)

 *    Flatliners (1990)

 *    Footloose (1984)

 *    Friday the 13th (1980)

 *    …

 *  Tin Men (1987)

 *    DeBoy, David

 *    Blumenfeld, Alan

 *    …

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 LookupIndex} class provides a data-driven client for reading in a

 *  key-value pairs from a file; then, printing the values corresponding to the

 *  keys found on standard input. Keys are strings; values are lists of strings.

 *  The separating delimiter is taken as a command-line argument. This client

 *  is sometimes known as an inverted index.

 *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
LookupIndex
 
{
 

    
// Do not instantiate.

    
private
 
LookupIndex
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 filename  
=
 args
[
0
];

        
String
 separator 
=
 args
[
1
];

        
In
 in 
=
 
new
 
In
(
filename
);

        ST
< String ,   Queue < String >>
 st 
=
 
new
 ST
< String ,   Queue < String >>
();

        ST
< String ,   Queue < String >>
 ts 
=
 
new
 ST
< String ,   Queue < String >>
();

        
while
 
(
in
.
hasNextLine
())
 
{

            
String
 line 
=
 in
.
readLine
();

            
String
[]
 fields 
=
 line
.
split
(
separator
);

            
String
 key 
=
 fields
[
0
];

            
for
 
(
int
 i 
=
 
1
;
 i 
<  fields . length ;  i ++ )   {                  String  val  =  fields [ i ];                  if   ( ! st . contains ( key ))  st . put ( key ,   new   Queue < String >
());

                
if
 
(
!
ts
.
contains
(
val
))
 ts
.
put
(
val
,
 
new
 
Queue
< String >
());

                st
.
get
(
key
).
enqueue
(
val
);

                ts
.
get
(
val
).
enqueue
(
key
);

            
}

        
}

        
StdOut
.
println
(
“Done indexing”
);

        
// read queries from standard input, one per line

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 query 
=
 
StdIn
.
readLine
();

            
if
 
(
st
.
contains
(
query
))
 

                
for
 
(
String
 vals 
:
 st
.
get
(
query
))

                    
StdOut
.
println
(
”  ”
 
+
 vals
);

            
if
 
(
ts
.
contains
(
query
))
 

                
for
 
(
String
 keys 
:
 ts
.
get
(
query
))

                    
StdOut
.
println
(
”  ”
 
+
 keys
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/LSD.java
edu/princeton/cs/algs4/LSD.java
/******************************************************************************

 *  Compilation:  javac LSD.java

 *  Execution:    java LSD < input.txt  *  Dependencies: StdIn.java StdOut.java   *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *  *  LSD radix sort  *  *    - Sort a String[] array of n extended ASCII strings (R = 256), each of length w.  *  *    - Sort an int[] array of n 32-bit integers, treating each integer as   *      a sequence of w = 4 bytes (R = 256).  *  *  Uses extra space proportional to n + R.  *  *  *  % java LSD < words3.txt  *  all  *  bad  *  bed  *  bug  *  dad  *  ...  *  yes  *  yet  *  zoo  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  LSD} class provides static methods for sorting an  *  array of w-character strings or 32-bit integers using LSD radix sort.

 *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 LSD 
{

    
private
 
static
 
final
 
int
 BITS_PER_BYTE 
=
 
8
;

    
// do not instantiate

    
private
 LSD
()
 
{
 
}

   
/**  

     * Rearranges the array of w-character strings in ascending order.

     *

     * 
@param
 a the array to be sorted

     * 
@param
 w the number of characters per string

     */

    
public
 
static
 
void
 sort
(
String
[]
 a
,
 
int
 w
)
 
{

        
int
 n 
=
 a
.
length
;

        
int
 R 
=
 
256
;
   
// extend ASCII alphabet size

        
String
[]
 aux 
=
 
new
 
String
[
n
];

        
for
 
(
int
 d 
=
 w

1
;
 d 
>=
 
0
;
 d

)
 
{

            
// sort by key-indexed counting on dth character

            
// compute frequency counts

            
int
[]
 count 
=
 
new
 
int
[
R
+
1
];

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )                 count [ a [ i ]. charAt ( d )   +   1 ] ++ ;              // compute cumulates              for   ( int  r  =   0 ;  r  <  R ;  r ++ )                 count [ r + 1 ]   +=  count [ r ];              // move data              for   ( int  i  =   0 ;  i  <  n ;  i ++ )                 aux [ count [ a [ i ]. charAt ( d )] ++ ]   =  a [ i ];              // copy back              for   ( int  i  =   0 ;  i  <  n ;  i ++ )                 a [ i ]   =  aux [ i ];          }      }     /**      * Rearranges the array of 32-bit integers in ascending order.      * This is about 2-3x faster than Arrays.sort().      *      *  @param  a the array to be sorted      */      public   static   void  sort ( int []  a )   {          final   int  BITS  =   32 ;                   // each int is 32 bits           final   int  R  =   1   <<  BITS_PER_BYTE ;      // each bytes is between 0 and 255          final   int  MASK  =  R  -   1 ;                // 0xFF          final   int  w  =  BITS  /  BITS_PER_BYTE ;    // each int is 4 bytes          int  n  =  a . length ;          int []  aux  =   new   int [ n ];          for   ( int  d  =   0 ;  d  <  w ;  d ++ )   {                        // compute frequency counts              int []  count  =   new   int [ R + 1 ];              for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                              int  c  =   ( a [ i ]   >>
 BITS_PER_BYTE
*
d
)
 
&
 MASK
;

                count
[

+
 
1
]
++
;

            
}

            
// compute cumulates

            
for
 
(
int
 r 
=
 
0
;
 r 
<  R ;  r ++ )                 count [ r + 1 ]   +=  count [ r ];              // for most significant byte, 0x80-0xFF comes before 0x00-0x7F              if   ( d  ==  w - 1 )   {                  int  shift1  =  count [ R ]   -  count [ R / 2 ];                  int  shift2  =  count [ R / 2 ];                  for   ( int  r  =   0 ;  r  <  R / 2 ;  r ++ )                     count [ r ]   +=  shift1 ;                  for   ( int  r  =  R / 2 ;  r  <  R ;  r ++ )                     count [ r ]   -=  shift2 ;              }              // move data              for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                  int  c  =   ( a [ i ]   >>
 BITS_PER_BYTE
*
d
)
 
&
 MASK
;

                aux
[
count
[
c
]
++
]
 
=
 a
[
i
];

            
}

            
// copy back

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )                 a [ i ]   =  aux [ i ];          }      }      /**      * Reads in a sequence of fixed-length strings from standard input;      * LSD radix sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          int  n  =  a . length ;          // check that strings have fixed length          int  w  =  a [ 0 ]. length ();          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              assert  a [ i ]. length ()   ==  w  :   "Strings must have fixed length" ;          // sort the strings         sort ( a ,  w );          // print results          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/LZW.java edu/princeton/cs/algs4/LZW.java /******************************************************************************  *  Compilation:  javac LZW.java  *  Execution:    java LZW - < input.txt   (compress)  *  Execution:    java LZW + < input.txt   (expand)  *  Dependencies: BinaryIn.java BinaryOut.java  *  Data files:   https://algs4.cs.princeton.edu/55compression/abraLZW.txt  *                https://algs4.cs.princeton.edu/55compression/ababLZW.txt  *  *  Compress or expand binary input from standard input using LZW.  *  *  WARNING: STARTING WITH ORACLE JAVA 6, UPDATE 7 the SUBSTRING  *  METHOD TAKES TIME AND SPACE LINEAR IN THE SIZE OF THE EXTRACTED  *  SUBSTRING (INSTEAD OF CONSTANT SPACE AND TIME AS IN EARLIER  *  IMPLEMENTATIONS).  *  *  See this article

 *  for more details.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 LZW} class provides static methods for compressing

 *  and expanding a binary input using LZW compression over the 8-bit extended

 *  ASCII alphabet with 12-bit codewords.

 *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick  

 *  
@author
 Kevin Wayne

 */

public
 
class
 LZW 
{

    
private
 
static
 
final
 
int
 R 
=
 
256
;
        
// number of input chars

    
private
 
static
 
final
 
int
 L 
=
 
4096
;
       
// number of codewords = 2^W

    
private
 
static
 
final
 
int
 W 
=
 
12
;
         
// codeword width

    
// Do not instantiate.

    
private
 LZW
()
 
{
 
}

    
/**

     * Reads a sequence of 8-bit bytes from standard input; compresses

     * them using LZW compression with 12-bit codewords; and writes the results

     * to standard output.

     */

    
public
 
static
 
void
 compress
()
 
{
 

        
String
 input 
=
 
BinaryStdIn
.
readString
();

        TST
< Integer >
 st 
=
 
new
 TST
< Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  R ;  i ++ )             st . put ( ""   +   ( char )  i ,  i );          int  code  =  R + 1 ;    // R is codeword for EOF          while   ( input . length ()   >
 
0
)
 
{

            
String
 s 
=
 st
.
longestPrefixOf
(
input
);
  
// Find max prefix match s.

            
BinaryStdOut
.
write
(
st
.
get
(
s
),
 W
);
      
// Print s’s encoding.

            
int
 t 
=
 s
.
length
();

            
if
 
(

<  input . length ()   &&  code  <  L )      // Add s to symbol table.                 st . put ( input . substring ( 0 ,  t  +   1 ),  code ++ );             input  =  input . substring ( t );              // Scan past s in input.          }          BinaryStdOut . write ( R ,  W );          BinaryStdOut . close ();      }        /**      * Reads a sequence of bit encoded using LZW compression with      * 12-bit codewords from standard input; expands them; and writes      * the results to standard output.      */      public   static   void  expand ()   {          String []  st  =   new   String [ L ];          int  i ;   // next available codeword value          // initialize symbol table with all 1-character strings          for   ( i  =   0 ;  i  <  R ;  i ++ )             st [ i ]   =   ""   +   ( char )  i ;         st [ i ++ ]   =   "" ;                          // (unused) lookahead for EOF          int  codeword  =   BinaryStdIn . readInt ( W );          if   ( codeword  ==  R )   return ;             // expanded message is empty string          String  val  =  st [ codeword ];          while   ( true )   {              BinaryStdOut . write ( val );             codeword  =   BinaryStdIn . readInt ( W );              if   ( codeword  ==  R )   break ;              String  s  =  st [ codeword ];              if   ( i  ==  codeword )  s  =  val  +  val . charAt ( 0 );     // special case hack              if   ( i  <  L )  st [ i ++ ]   =  val  +  s . charAt ( 0 );             val  =  s ;          }          BinaryStdOut . close ();      }      /**      * Sample client that calls { @code  compress()} if the command-line      * argument is "-" an { @code  expand()} if it is "+".      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          if        ( args [ 0 ]. equals ( "-" ))  compress ();          else   if   ( args [ 0 ]. equals ( "+" ))  expand ();          else   throw   new   IllegalArgumentException ( "Illegal command line argument" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/MaxPQ.java edu/princeton/cs/algs4/MaxPQ.java /******************************************************************************  *  Compilation:  javac MaxPQ.java  *  Execution:    java MaxPQ < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyPQ.txt  *    *  Generic max priority queue implementation with a binary heap.  *  Can be used with a comparator instead of the natural order,  *  but the generic Key type must still be Comparable.  *  *  % java MaxPQ < tinyPQ.txt   *  Q X P (6 left on pq)  *  *  We use a one-based array to simplify parent and child calculations.  *  *  Can be optimized by replacing full exchanges with half exchanges  *  (ala insertion sort).  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  MaxPQ} class represents a priority queue of generic keys.  *  It supports the usual insert and delete-the-maximum

 *  operations, along with methods for peeking at the maximum key,

 *  testing if the priority queue is empty, and iterating through

 *  the keys.

 *  

 *  This implementation uses a binary heap.

 *  The insert and delete-the-maximum operations take

 *  Θ(log n) amortized time, where n is the number

 *  of elements in the priority queue. This is an amortized bound 

 *  (and not a worst-case bound) because of array resizing operations.

 *  The minsize, and is-empty operations take 

 *  Θ(1) time in the worst case.

 *  Construction takes time proportional to the specified capacity or the

 *  number of items used to initialize the data structure.

 *  

 *  For additional documentation, see

 *  Section 2.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of key on this priority queue

 */

public
 
class
 
MaxPQ
< Key >
 
implements
 
Iterable
< Key >
 
{

    
private
 
Key
[]
 pq
;
                    
// store items at indices 1 to n

    
private
 
int
 n
;
                       
// number of items on priority queue

    
private
 
Comparator
< Key >
 comparator
;
  
// optional comparator

    
/**

     * Initializes an empty priority queue with the given initial capacity.

     *

     * 
@param
  initCapacity the initial capacity of this priority queue

     */

    
public
 
MaxPQ
(
int
 initCapacity
)
 
{

        pq 
=
 
(
Key
[])
 
new
 
Object
[
initCapacity 
+
 
1
];

        n 
=
 
0
;

    
}

    
/**

     * Initializes an empty priority queue.

     */

    
public
 
MaxPQ
()
 
{

        
this
(
1
);

    
}

    
/**

     * Initializes an empty priority queue with the given initial capacity,

     * using the given comparator.

     *

     * 
@param
  initCapacity the initial capacity of this priority queue

     * 
@param
  comparator the order in which to compare the keys

     */

    
public
 
MaxPQ
(
int
 initCapacity
,
 
Comparator
< Key >
 comparator
)
 
{

        
this
.
comparator 
=
 comparator
;

        pq 
=
 
(
Key
[])
 
new
 
Object
[
initCapacity 
+
 
1
];

        n 
=
 
0
;

    
}

    
/**

     * Initializes an empty priority queue using the given comparator.

     *

     * 
@param
  comparator the order in which to compare the keys

     */

    
public
 
MaxPQ
(
Comparator
< Key >
 comparator
)
 
{

        
this
(
1
,
 comparator
);

    
}

    
/**

     * Initializes a priority queue from the array of keys.

     * Takes time proportional to the number of keys, using sink-based heap construction.

     *

     * 
@param
  keys the array of keys

     */

    
public
 
MaxPQ
(
Key
[]
 keys
)
 
{

        n 
=
 keys
.
length
;

        pq 
=
 
(
Key
[])
 
new
 
Object
[
keys
.
length 
+
 
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             pq [ i + 1 ]   =  keys [ i ];          for   ( int  k  =  n / 2 ;  k  >=
 
1
;
 k

)

            sink
(
k
);

        
assert
 isMaxHeap
();

    
}

      

    
/**

     * Returns true if this priority queue is empty.

     *

     * 
@return
 {
@code
 true} if this priority queue is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 n 
==
 
0
;

    
}

    
/**

     * Returns the number of keys on this priority queue.

     *

     * 
@return
 the number of keys on this priority queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns a largest key on this priority queue.

     *

     * 
@return
 a largest key on this priority queue

     * 
@throws
 NoSuchElementException if this priority queue is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue underflow”
);

        
return
 pq
[
1
];

    
}

    
// helper function to double the size of the heap array

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>
 n
;

        
Key
[]
 temp 
=
 
(
Key
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {             temp [ i ]   =  pq [ i ];          }         pq  =  temp ;      }      /**      * Adds a new key to this priority queue.      *      *  @param   x the new key to add to this priority queue      */      public   void  insert ( Key  x )   {          // double size of array if necessary          if   ( n  ==  pq . length  -   1 )  resize ( 2   *  pq . length );          // add x, and percolate it up to maintain heap invariant         pq [ ++ n ]   =  x ;         swim ( n );          assert  isMaxHeap ();      }      /**      * Removes and returns a largest key on this priority queue.      *      *  @return  a largest key on this priority queue      *  @throws  NoSuchElementException if this priority queue is empty      */      public   Key  delMax ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );          Key  max  =  pq [ 1 ];         exch ( 1 ,  n -- );         sink ( 1 );         pq [ n + 1 ]   =   null ;       // to avoid loitering and help with garbage collection          if   (( n  >
 
0
)
 
&&
 
(

==
 
(
pq
.
length 

 
1
)
 
/
 
4
))
 resize
(
pq
.
length 
/
 
2
);

        
assert
 isMaxHeap
();

        
return
 max
;

    
}

   
/***************************************************************************

    * Helper functions to restore the heap invariant.

    ***************************************************************************/

    
private
 
void
 swim
(
int
 k
)
 
{

        
while
 
(

>
 
1
 
&&
 less
(
k
/
2
,
 k
))
 
{

            exch
(
k
,
 k
/
2
);

            k 
=
 k
/
2
;

        
}

    
}

    
private
 
void
 sink
(
int
 k
)
 
{

        
while
 
(
2
*

<=  n )   {              int  j  =   2 * k ;              if   ( j  <  n  &&  less ( j ,  j + 1 ))  j ++ ;              if   ( ! less ( k ,  j ))   break ;             exch ( k ,  j );             k  =  j ;          }      }     /***************************************************************************     * Helper functions for compares and swaps.     ***************************************************************************/      private   boolean  less ( int  i ,   int  j )   {          if   ( comparator  ==   null )   {              return   (( Comparable < Key >
)
 pq
[
i
]).
compareTo
(
pq
[
j
])
 
<   0 ;          }          else   {              return  comparator . compare ( pq [ i ],  pq [ j ])   <   0 ;          }      }      private   void  exch ( int  i ,   int  j )   {          Key  swap  =  pq [ i ];         pq [ i ]   =  pq [ j ];         pq [ j ]   =  swap ;      }      // is pq[1..n] a max heap?      private   boolean  isMaxHeap ()   {          for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {              if   ( pq [ i ]   ==   null )   return   false ;          }          for   ( int  i  =  n + 1 ;  i  <  pq . length ;  i ++ )   {              if   ( pq [ i ]   !=   null )   return   false ;          }          if   ( pq [ 0 ]   !=   null )   return   false ;          return  isMaxHeapOrdered ( 1 );      }      // is subtree of pq[1..n] rooted at k a max heap?      private   boolean  isMaxHeapOrdered ( int  k )   {          if   ( k  >
 n
)
 
return
 
true
;

        
int
 left 
=
 
2
*
k
;

        
int
 right 
=
 
2
*

+
 
1
;

        
if
 
(
left  
<=  n  &&  less ( k ,  left ))    return   false ;          if   ( right  <=  n  &&  less ( k ,  right ))   return   false ;          return  isMaxHeapOrdered ( left )   &&  isMaxHeapOrdered ( right );      }     /***************************************************************************     * Iterator.     ***************************************************************************/      /**      * Returns an iterator that iterates over the keys on this priority queue      * in descending order.      * The iterator doesn't implement { @code  remove()} since it's optional.      *      *  @return  an iterator that iterates over the keys in descending order      */      public   Iterator < Key >
 iterator
()
 
{

        
return
 
new
 
HeapIterator
();

    
}

    
private
 
class
 
HeapIterator
 
implements
 
Iterator
< Key >
 
{

        
// create a new pq

        
private
 
MaxPQ
< Key >
 copy
;

        
// add all items to copy of heap

        
// takes linear time since already in heap order so no keys move

        
public
 
HeapIterator
()
 
{

            
if
 
(
comparator 
==
 
null
)
 copy 
=
 
new
 
MaxPQ
< Key >
(
size
());

            
else
                    copy 
=
 
new
 
MaxPQ
< Key >
(
size
(),
 comparator
);

            
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )                 copy . insert ( pq [ i ]);          }          public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Key  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  copy . delMax ();          }      }      /**      * Unit tests the { @code  MaxPQ} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          MaxPQ < String >
 pq 
=
 
new
 
MaxPQ
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))
 pq
.
insert
(
item
);

            
else
 
if
 
(
!
pq
.
isEmpty
())
 
StdOut
.
print
(
pq
.
delMax
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 pq
.
size
()
 
+
 
” left on pq)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/MergeBU.java
edu/princeton/cs/algs4/MergeBU.java
/******************************************************************************

 *  Compilation:  javac MergeBU.java

 *  Execution:    java MergeBU < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt  *                https://algs4.cs.princeton.edu/22mergesort/words3.txt  *     *  Sorts a sequence of strings from standard input using  *  bottom-up mergesort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java MergeBU < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java MergeBU < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  MergeBU} class provides static methods for sorting an  *  array using bottom-up mergesort. It is non-recursive.

 *  

 *  This implementation takes Θ(n log n) time

 *  to sort any array of length n (assuming comparisons

 *  take constant time). It makes between

 *  ~ ½ n log2 n and

 *  ~ 1 n log2 n compares.

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(n) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
MergeBU
 
{

    
// This class should not be instantiated.

    
private
 
MergeBU
()
 
{
 
}

    
// stably merge a[lo..mid] with a[mid+1..hi] using aux[lo..hi]

    
private
 
static
 
void
 merge
(
Comparable
[]
 a
,
 
Comparable
[]
 aux
,
 
int
 lo
,
 
int
 mid
,
 
int
 hi
)
 
{

        
// copy to aux[]

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  hi ;  k ++ )   {             aux [ k ]   =  a [ k ];            }          // merge back to a[]          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
              a
[
k
]
 
=
 aux
[
j
++
];
  
// this copying is unneccessary

            
else
 
if
 
(

>
 hi
)
               a
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
less
(
aux
[
j
],
 aux
[
i
]))
 a
[
k
]
 
=
 aux
[
j
++
];

            
else
                           a
[
k
]
 
=
 aux
[
i
++
];

        
}

    
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
Comparable
[]
 aux 
=
 
new
 
Comparable
[
n
];

        
for
 
(
int
 len 
=
 
1
;
 len 
<  n ;  len  *=   2 )   {              for   ( int  lo  =   0 ;  lo  <  n - len ;  lo  +=  len + len )   {                  int  mid   =  lo + len - 1 ;                  int  hi  =   Math . min ( lo + len + len - 1 ,  n - 1 );                 merge ( a ,  aux ,  lo ,  mid ,  hi );              }          }          assert  isSorted ( a );      }    /***********************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; bottom-up      * mergesorts them; and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          MergeBU . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Merge.java edu/princeton/cs/algs4/Merge.java /******************************************************************************  *  Compilation:  javac Merge.java  *  Execution:    java Merge < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt  *                https://algs4.cs.princeton.edu/22mergesort/words3.txt  *     *  Sorts a sequence of strings from standard input using mergesort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Merge < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java Merge < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Merge} class provides static methods for sorting an  *  array using a top-down, recursive version of mergesort.

 *  

 *  This implementation takes Θ(n log n) time

 *  to sort any array of length n (assuming comparisons

 *  take constant time). It makes between

 *  ~ ½ n log2 n and

 *  ~ 1 n log2 n compares.

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(n) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For an optimized version, see {
@link
 MergeX}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Merge
 
{

    
// This class should not be instantiated.

    
private
 
Merge
()
 
{
 
}

    
// stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]

    
private
 
static
 
void
 merge
(
Comparable
[]
 a
,
 
Comparable
[]
 aux
,
 
int
 lo
,
 
int
 mid
,
 
int
 hi
)
 
{

        
// precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays

        
assert
 isSorted
(
a
,
 lo
,
 mid
);

        
assert
 isSorted
(
a
,
 mid
+
1
,
 hi
);

        
// copy to aux[]

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  hi ;  k ++ )   {             aux [ k ]   =  a [ k ];            }          // merge back to a[]          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
              a
[
k
]
 
=
 aux
[
j
++
];

            
else
 
if
 
(

>
 hi
)
               a
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
less
(
aux
[
j
],
 aux
[
i
]))
 a
[
k
]
 
=
 aux
[
j
++
];

            
else
                           a
[
k
]
 
=
 aux
[
i
++
];

        
}

        
// postcondition: a[lo .. hi] is sorted

        
assert
 isSorted
(
a
,
 lo
,
 hi
);

    
}

    
// mergesort a[lo..hi] using auxiliary array aux[lo..hi]

    
private
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
Comparable
[]
 aux
,
 
int
 lo
,
 
int
 hi
)
 
{

        
if
 
(
hi 
<=  lo )   return ;          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         sort ( a ,  aux ,  lo ,  mid );         sort ( a ,  aux ,  mid  +   1 ,  hi );         merge ( a ,  aux ,  lo ,  mid ,  hi );      }      /**      * Rearranges the array in ascending order, using the natural order.      *  @param  a the array to be sorted      */      public   static   void  sort ( Comparable []  a )   {          Comparable []  aux  =   new   Comparable [ a . length ];         sort ( a ,  aux ,   0 ,  a . length - 1 );          assert  isSorted ( a );      }     /***************************************************************************     *  Helper sorting function.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }              /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length  -   1 );      }      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }     /***************************************************************************     *  Index mergesort.     ***************************************************************************/      // stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]      private   static   void  merge ( Comparable []  a ,   int []  index ,   int []  aux ,   int  lo ,   int  mid ,   int  hi )   {          // copy to aux[]          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {             aux [ k ]   =  index [ k ];            }          // merge back to a[]          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
                    index
[
k
]
 
=
 aux
[
j
++
];

            
else
 
if
 
(

>
 hi
)
                     index
[
k
]
 
=
 aux
[
i
++
];

            
else
 
if
 
(
less
(
a
[
aux
[
j
]],
 a
[
aux
[
i
]]))
 index
[
k
]
 
=
 aux
[
j
++
];

            
else
                                 index
[
k
]
 
=
 aux
[
i
++
];

        
}

    
}

    
/**

     * Returns a permutation that gives the elements in the array in ascending order.

     * 
@param
 a the array

     * 
@return
 a permutation {
@code
 p[]} such that {
@code
 a[p[0]]}, {
@code
 a[p[1]]},

     *    …, {
@code
 a[p[N-1]]} are in ascending order

     */

    
public
 
static
 
int
[]
 indexSort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
int
[]
 index 
=
 
new
 
int
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             index [ i ]   =  i ;          int []  aux  =   new   int [ n ];         sort ( a ,  index ,  aux ,   0 ,  n - 1 );          return  index ;      }      // mergesort a[lo..hi] using auxiliary array aux[lo..hi]      private   static   void  sort ( Comparable []  a ,   int []  index ,   int []  aux ,   int  lo ,   int  hi )   {          if   ( hi  <=  lo )   return ;          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         sort ( a ,  index ,  aux ,  lo ,  mid );         sort ( a ,  index ,  aux ,  mid  +   1 ,  hi );         merge ( a ,  index ,  aux ,  lo ,  mid ,  hi );      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; mergesorts them;       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Merge . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/MergeX.java edu/princeton/cs/algs4/MergeX.java /******************************************************************************  *  Compilation:  javac MergeX.java  *  Execution:    java MergeX < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt  *                https://algs4.cs.princeton.edu/22mergesort/words3.txt  *     *  Sorts a sequence of strings from standard input using an  *  optimized version of mergesort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java MergeX < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java MergeX < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; /**  *  The { @code  MergeX} class provides static methods for sorting an  *  array using an optimized version of mergesort.  *  

 *  In the worst case, this implementation takes

 *  Θ(n log n) time to sort an array of

 *  length n (assuming comparisons take constant time).

 *  

 *  This sorting algorithm is stable.

 *  It uses Θ(n) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
MergeX
 
{

    
private
 
static
 
final
 
int
 CUTOFF 
=
 
7
;
  
// cutoff to insertion sort

    
// This class should not be instantiated.

    
private
 
MergeX
()
 
{
 
}

    
private
 
static
 
void
 merge
(
Comparable
[]
 src
,
 
Comparable
[]
 dst
,
 
int
 lo
,
 
int
 mid
,
 
int
 hi
)
 
{

        
// precondition: src[lo .. mid] and src[mid+1 .. hi] are sorted subarrays

        
assert
 isSorted
(
src
,
 lo
,
 mid
);

        
assert
 isSorted
(
src
,
 mid
+
1
,
 hi
);

        
int
 i 
=
 lo
,
 j 
=
 mid
+
1
;

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  hi ;  k ++ )   {              if        ( i  >
 mid
)
              dst
[
k
]
 
=
 src
[
j
++
];

            
else
 
if
 
(

>
 hi
)
               dst
[
k
]
 
=
 src
[
i
++
];

            
else
 
if
 
(
less
(
src
[
j
],
 src
[
i
]))
 dst
[
k
]
 
=
 src
[
j
++
];
   
// to ensure stability

            
else
                           dst
[
k
]
 
=
 src
[
i
++
];

        
}

        
// postcondition: dst[lo .. hi] is sorted subarray

        
assert
 isSorted
(
dst
,
 lo
,
 hi
);

    
}

    
private
 
static
 
void
 sort
(
Comparable
[]
 src
,
 
Comparable
[]
 dst
,
 
int
 lo
,
 
int
 hi
)
 
{

        
// if (hi <= lo) return;          if   ( hi  <=  lo  +  CUTOFF )   {               insertionSort ( dst ,  lo ,  hi );              return ;          }          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         sort ( dst ,  src ,  lo ,  mid );         sort ( dst ,  src ,  mid + 1 ,  hi );          // if (!less(src[mid+1], src[mid])) {          //    for (int i = lo; i <= hi; i++) dst[i] = src[i];          //    return;          // }          // using System.arraycopy() is a bit faster than the above loop          if   ( ! less ( src [ mid + 1 ],  src [ mid ]))   {              System . arraycopy ( src ,  lo ,  dst ,  lo ,  hi  -  lo  +   1 );              return ;          }         merge ( src ,  dst ,  lo ,  mid ,  hi );      }      /**      * Rearranges the array in ascending order, using the natural order.      *  @param  a the array to be sorted      */      public   static   void  sort ( Comparable []  a )   {          Comparable []  aux  =  a . clone ();         sort ( aux ,  a ,   0 ,  a . length - 1 );             assert  isSorted ( a );      }      // sort from a[lo] to a[hi] using insertion sort      private   static   void  insertionSort ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
]);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
/*******************************************************************

     *  Utility methods.

     *******************************************************************/

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
Object
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
Object
 swap 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 swap
;

    
}

    
// is a[i] < a[j]?      private   static   boolean  less ( Comparable  a ,   Comparable  b )   {          return  a . compareTo ( b )   <   0 ;      }      // is a[i] < a[j]?      private   static   boolean  less ( Object  a ,   Object  b ,   Comparator  comparator )   {          return  comparator . compare ( a ,  b )   <   0 ;      }      /*******************************************************************      *  Version that takes Comparator as argument.      *******************************************************************/      /**      * Rearranges the array in ascending order, using the provided order.      *      *  @param  a the array to be sorted      *  @param  comparator the comparator that defines the total order      */      public   static   void  sort ( Object []  a ,   Comparator  comparator )   {          Object []  aux  =  a . clone ();         sort ( aux ,  a ,   0 ,  a . length - 1 ,  comparator );          assert  isSorted ( a ,  comparator );      }      private   static   void  merge ( Object []  src ,   Object []  dst ,   int  lo ,   int  mid ,   int  hi ,   Comparator  comparator )   {          // precondition: src[lo .. mid] and src[mid+1 .. hi] are sorted subarrays          assert  isSorted ( src ,  lo ,  mid ,  comparator );          assert  isSorted ( src ,  mid + 1 ,  hi ,  comparator );          int  i  =  lo ,  j  =  mid + 1 ;          for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {              if        ( i  >
 mid
)
                          dst
[
k
]
 
=
 src
[
j
++
];

            
else
 
if
 
(

>
 hi
)
                           dst
[
k
]
 
=
 src
[
i
++
];

            
else
 
if
 
(
less
(
src
[
j
],
 src
[
i
],
 comparator
))
 dst
[
k
]
 
=
 src
[
j
++
];

            
else
                                       dst
[
k
]
 
=
 src
[
i
++
];

        
}

        
// postcondition: dst[lo .. hi] is sorted subarray

        
assert
 isSorted
(
dst
,
 lo
,
 hi
,
 comparator
);

    
}

    
private
 
static
 
void
 sort
(
Object
[]
 src
,
 
Object
[]
 dst
,
 
int
 lo
,
 
int
 hi
,
 
Comparator
 comparator
)
 
{

        
// if (hi <= lo) return;          if   ( hi  <=  lo  +  CUTOFF )   {               insertionSort ( dst ,  lo ,  hi ,  comparator );              return ;          }          int  mid  =  lo  +   ( hi  -  lo )   /   2 ;         sort ( dst ,  src ,  lo ,  mid ,  comparator );         sort ( dst ,  src ,  mid + 1 ,  hi ,  comparator );          // using System.arraycopy() is a bit faster than the above loop          if   ( ! less ( src [ mid + 1 ],  src [ mid ],  comparator ))   {              System . arraycopy ( src ,  lo ,  dst ,  lo ,  hi  -  lo  +   1 );              return ;          }         merge ( src ,  dst ,  lo ,  mid ,  hi ,  comparator );      }      // sort from a[lo] to a[hi] using insertion sort      private   static   void  insertionSort ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 comparator
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

   
/***************************************************************************

    *  Check if array is sorted – useful for debugging.

    ***************************************************************************/

    
private
 
static
 
boolean
 isSorted
(
Comparable
[]
 a
)
 
{

        
return
 isSorted
(
a
,
 
0
,
 a
.
length 

 
1
);

    
}

    
private
 
static
 
boolean
 isSorted
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{

        
for
 
(
int
 i 
=
 lo 
+
 
1
;
 i 
<=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {          return  isSorted ( a ,   0 ,  a . length  -   1 ,  comparator );      }      private   static   boolean  isSorted ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ],  comparator ))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Object []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; mergesorts them      * (using an optimized version of mergesort);       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          MergeX . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/MinPQ.java edu/princeton/cs/algs4/MinPQ.java /******************************************************************************  *  Compilation:  javac MinPQ.java  *  Execution:    java MinPQ < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyPQ.txt  *    *  Generic min priority queue implementation with a binary heap.  *  Can be used with a comparator instead of the natural order.  *  *  % java MinPQ < tinyPQ.txt  *  E A E (6 left on pq)  *  *  We use a one-based array to simplify parent and child calculations.  *  *  Can be optimized by replacing full exchanges with half exchanges  *  (ala insertion sort).  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  MinPQ} class represents a priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum

 *  operations, along with methods for peeking at the minimum key,

 *  testing if the priority queue is empty, and iterating through

 *  the keys.

 *  

 *  This implementation uses a binary heap.

 *  The insert and delete-the-minimum operations take

 *  Θ(log n) amortized time, where n is the number

 *  of elements in the priority queue. This is an amortized bound

 *  (and not a worst-case bound) because of array resizing operations.

 *  The minsize, and is-empty operations take

 *  Θ(1) time in the worst case.

 *  Construction takes time proportional to the specified capacity or the

 *  number of items used to initialize the data structure.

 *  

 *  For additional documentation, see

 *  Section 2.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of key on this priority queue

 */

public
 
class
 
MinPQ
< Key >
 
implements
 
Iterable
< Key >
 
{

    
private
 
Key
[]
 pq
;
                    
// store items at indices 1 to n

    
private
 
int
 n
;
                       
// number of items on priority queue

    
private
 
Comparator
< Key >
 comparator
;
  
// optional comparator

    
/**

     * Initializes an empty priority queue with the given initial capacity.

     *

     * 
@param
  initCapacity the initial capacity of this priority queue

     */

    
public
 
MinPQ
(
int
 initCapacity
)
 
{

        pq 
=
 
(
Key
[])
 
new
 
Object
[
initCapacity 
+
 
1
];

        n 
=
 
0
;

    
}

    
/**

     * Initializes an empty priority queue.

     */

    
public
 
MinPQ
()
 
{

        
this
(
1
);

    
}

    
/**

     * Initializes an empty priority queue with the given initial capacity,

     * using the given comparator.

     *

     * 
@param
  initCapacity the initial capacity of this priority queue

     * 
@param
  comparator the order in which to compare the keys

     */

    
public
 
MinPQ
(
int
 initCapacity
,
 
Comparator
< Key >
 comparator
)
 
{

        
this
.
comparator 
=
 comparator
;

        pq 
=
 
(
Key
[])
 
new
 
Object
[
initCapacity 
+
 
1
];

        n 
=
 
0
;

    
}

    
/**

     * Initializes an empty priority queue using the given comparator.

     *

     * 
@param
  comparator the order in which to compare the keys

     */

    
public
 
MinPQ
(
Comparator
< Key >
 comparator
)
 
{

        
this
(
1
,
 comparator
);

    
}

    
/**

     * Initializes a priority queue from the array of keys.

     * 

     * Takes time proportional to the number of keys, using sink-based heap construction.

     *

     * 
@param
  keys the array of keys

     */

    
public
 
MinPQ
(
Key
[]
 keys
)
 
{

        n 
=
 keys
.
length
;

        pq 
=
 
(
Key
[])
 
new
 
Object
[
keys
.
length 
+
 
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             pq [ i + 1 ]   =  keys [ i ];          for   ( int  k  =  n / 2 ;  k  >=
 
1
;
 k

)

            sink
(
k
);

        
assert
 isMinHeap
();

    
}

    
/**

     * Returns true if this priority queue is empty.

     *

     * 
@return
 {
@code
 true} if this priority queue is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 n 
==
 
0
;

    
}

    
/**

     * Returns the number of keys on this priority queue.

     *

     * 
@return
 the number of keys on this priority queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns a smallest key on this priority queue.

     *

     * 
@return
 a smallest key on this priority queue

     * 
@throws
 NoSuchElementException if this priority queue is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Priority queue underflow”
);

        
return
 pq
[
1
];

    
}

    
// helper function to double the size of the heap array

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>
 n
;

        
Key
[]
 temp 
=
 
(
Key
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {             temp [ i ]   =  pq [ i ];          }         pq  =  temp ;      }      /**      * Adds a new key to this priority queue.      *      *  @param   x the key to add to this priority queue      */      public   void  insert ( Key  x )   {          // double size of array if necessary          if   ( n  ==  pq . length  -   1 )  resize ( 2   *  pq . length );          // add x, and percolate it up to maintain heap invariant         pq [ ++ n ]   =  x ;         swim ( n );          assert  isMinHeap ();      }      /**      * Removes and returns a smallest key on this priority queue.      *      *  @return  a smallest key on this priority queue      *  @throws  NoSuchElementException if this priority queue is empty      */      public   Key  delMin ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );          Key  min  =  pq [ 1 ];         exch ( 1 ,  n -- );         sink ( 1 );         pq [ n + 1 ]   =   null ;       // to avoid loiterig and help with garbage collection          if   (( n  >
 
0
)
 
&&
 
(

==
 
(
pq
.
length 

 
1
)
 
/
 
4
))
 resize
(
pq
.
length 
/
 
2
);

        
assert
 isMinHeap
();

        
return
 min
;

    
}

   
/***************************************************************************

    * Helper functions to restore the heap invariant.

    ***************************************************************************/

    
private
 
void
 swim
(
int
 k
)
 
{

        
while
 
(

>
 
1
 
&&
 greater
(
k
/
2
,
 k
))
 
{

            exch
(
k
,
 k
/
2
);

            k 
=
 k
/
2
;

        
}

    
}

    
private
 
void
 sink
(
int
 k
)
 
{

        
while
 
(
2
*

<=  n )   {              int  j  =   2 * k ;              if   ( j  <  n  &&  greater ( j ,  j + 1 ))  j ++ ;              if   ( ! greater ( k ,  j ))   break ;             exch ( k ,  j );             k  =  j ;          }      }     /***************************************************************************     * Helper functions for compares and swaps.     ***************************************************************************/      private   boolean  greater ( int  i ,   int  j )   {          if   ( comparator  ==   null )   {              return   (( Comparable < Key >
)
 pq
[
i
]).
compareTo
(
pq
[
j
])
 
>
 
0
;

        
}

        
else
 
{

            
return
 comparator
.
compare
(
pq
[
i
],
 pq
[
j
])
 
>
 
0
;

        
}

    
}

    
private
 
void
 exch
(
int
 i
,
 
int
 j
)
 
{

        
Key
 swap 
=
 pq
[
i
];

        pq
[
i
]
 
=
 pq
[
j
];

        pq
[
j
]
 
=
 swap
;

    
}

    
// is pq[1..n] a min heap?

    
private
 
boolean
 isMinHeap
()
 
{

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {              if   ( pq [ i ]   ==   null )   return   false ;          }          for   ( int  i  =  n + 1 ;  i  <  pq . length ;  i ++ )   {              if   ( pq [ i ]   !=   null )   return   false ;          }          if   ( pq [ 0 ]   !=   null )   return   false ;          return  isMinHeapOrdered ( 1 );      }      // is subtree of pq[1..n] rooted at k a min heap?      private   boolean  isMinHeapOrdered ( int  k )   {          if   ( k  >
 n
)
 
return
 
true
;

        
int
 left 
=
 
2
*
k
;

        
int
 right 
=
 
2
*

+
 
1
;

        
if
 
(
left  
<=  n  &&  greater ( k ,  left ))    return   false ;          if   ( right  <=  n  &&  greater ( k ,  right ))   return   false ;          return  isMinHeapOrdered ( left )   &&  isMinHeapOrdered ( right );      }      /**      * Returns an iterator that iterates over the keys on this priority queue      * in ascending order.      * 

     * The iterator doesn’t implement {
@code
 remove()} since it’s optional.

     *

     * 
@return
 an iterator that iterates over the keys in ascending order

     */

    
public
 
Iterator
< Key >
 iterator
()
 
{

        
return
 
new
 
HeapIterator
();

    
}

    
private
 
class
 
HeapIterator
 
implements
 
Iterator
< Key >
 
{

        
// create a new pq

        
private
 
MinPQ
< Key >
 copy
;

        
// add all items to copy of heap

        
// takes linear time since already in heap order so no keys move

        
public
 
HeapIterator
()
 
{

            
if
 
(
comparator 
==
 
null
)
 copy 
=
 
new
 
MinPQ
< Key >
(
size
());

            
else
                    copy 
=
 
new
 
MinPQ
< Key >
(
size
(),
 comparator
);

            
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )                 copy . insert ( pq [ i ]);          }          public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Key  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  copy . delMin ();          }      }      /**      * Unit tests the { @code  MinPQ} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          MinPQ < String >
 pq 
=
 
new
 
MinPQ
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))
 pq
.
insert
(
item
);

            
else
 
if
 
(
!
pq
.
isEmpty
())
 
StdOut
.
print
(
pq
.
delMin
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 pq
.
size
()
 
+
 
” left on pq)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/MSD.java
edu/princeton/cs/algs4/MSD.java
/******************************************************************************

 *  Compilation: javac MSD.java

 *  Execution:   java MSD < input.txt  *  Dependencies: StdIn.java StdOut.java   *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *                https://algs4.cs.princeton.edu/51radix/shells.txt  *  *  Sort an array of strings or integers using MSD radix sort.  *  *  % java MSD < shells.txt   *  are  *  by  *  sea  *  seashells  *  seashells  *  sells  *  sells  *  she  *  she  *  shells  *  shore  *  surely  *  the  *  the  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  MSD} class provides static methods for sorting an  *  array of extended ASCII strings or integers using MSD radix sort.  *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 MSD 
{

    
private
 
static
 
final
 
int
 BITS_PER_BYTE 
=
   
8
;

    
private
 
static
 
final
 
int
 BITS_PER_INT  
=
  
32
;
   
// each Java int is 32 bits 

    
private
 
static
 
final
 
int
 R             
=
 
256
;
   
// extended ASCII alphabet size

    
private
 
static
 
final
 
int
 CUTOFF        
=
  
15
;
   
// cutoff to insertion sort

    
// do not instantiate

    
private
 MSD
()
 
{
 
}
 

   
/**

     * Rearranges the array of extended ASCII strings in ascending order.

     *

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
String
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
String
[]
 aux 
=
 
new
 
String
[
n
];

        sort
(
a
,
 
0
,
 n

1
,
 
0
,
 aux
);

    
}

    
// return dth character of s, -1 if d = length of string

    
private
 
static
 
int
 charAt
(
String
 s
,
 
int
 d
)
 
{

        
assert
 d 
>=
 
0
 
&&
 d 
<=  s . length ();          if   ( d  ==  s . length ())   return   - 1 ;          return  s . charAt ( d );      }      // sort from a[lo] to a[hi], starting at the dth character      private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d ,   String []  aux )   {          // cutoff to insertion sort for small subarrays          if   ( hi  <=  lo  +  CUTOFF )   {             insertion ( a ,  lo ,  hi ,  d );              return ;          }          // compute frequency counts          int []  count  =   new   int [ R + 2 ];          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              int  c  =  charAt ( a [ i ],  d );             count [ c + 2 ] ++ ;          }          // transform counts to indicies          for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )             count [ r + 1 ]   +=  count [ r ];          // distribute          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              int  c  =  charAt ( a [ i ],  d );             aux [ count [ c + 1 ] ++ ]   =  a [ i ];          }          // copy back          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )               a [ i ]   =  aux [ i  -  lo ];          // recursively sort for each character (excludes sentinel -1)          for   ( int  r  =   0 ;  r  <  R ;  r ++ )             sort ( a ,  lo  +  count [ r ],  lo  +  count [ r + 1 ]   -   1 ,  d + 1 ,  aux );      }      // insertion sort a[lo..hi], starting at dth character      private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
String
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
String
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    
// is v less than w, starting at character d

    
private
 
static
 
boolean
 less
(
String
 v
,
 
String
 w
,
 
int
 d
)
 
{

        
// assert v.substring(0, d).equals(w.substring(0, d));

        
for
 
(
int
 i 
=
 d
;
 i 
<   Math . min ( v . length (),  w . length ());  i ++ )   {              if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;              if   ( v . charAt ( i )   >
 w
.
charAt
(
i
))
 
return
 
false
;

        
}

        
return
 v
.
length
()
 
<  w . length ();      }     /**      * Rearranges the array of 32-bit integers in ascending order.      * Currently assumes that the integers are nonnegative.      *      *  @param  a the array to be sorted      */      public   static   void  sort ( int []  a )   {          int  n  =  a . length ;          int []  aux  =   new   int [ n ];         sort ( a ,   0 ,  n - 1 ,   0 ,  aux );      }      // MSD sort from a[lo] to a[hi], starting at the dth byte      private   static   void  sort ( int []  a ,   int  lo ,   int  hi ,   int  d ,   int []  aux )   {          // cutoff to insertion sort for small subarrays          if   ( hi  <=  lo  +  CUTOFF )   {             insertion ( a ,  lo ,  hi ,  d );              return ;          }          // compute frequency counts (need R = 256)          int []  count  =   new   int [ R + 1 ];          int  mask  =  R  -   1 ;     // 0xFF;          int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * d  -  BITS_PER_BYTE ;          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              int  c  =   ( a [ i ]   >>
 shift
)
 
&
 mask
;

            count
[

+
 
1
]
++
;

        
}

        
// transform counts to indicies

        
for
 
(
int
 r 
=
 
0
;
 r 
<  R ;  r ++ )             count [ r + 1 ]   +=  count [ r ]; /************* BUGGGY CODE.         // for most significant byte, 0x80-0xFF comes before 0x00-0x7F         if (d == 0) {             int shift1 = count[R] - count[R/2];             int shift2 = count[R/2];             for (int r = 0; r < R/2; r++)                 count[r] += shift1;             for (int r = R/2; r < R; r++)                 count[r] -= shift2;         } ************************************/          // distribute          for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {              int  c  =   ( a [ i ]   >>
 shift
)
 
&
 mask
;

            aux
[
count
[
c
]
++
]
 
=
 a
[
i
];

        
}

        
// copy back

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )               a [ i ]   =  aux [ i  -  lo ];          // no more bits          if   ( d  ==   4 )   return ;          // recursively sort for each character          if   ( count [ 0 ]   >
 
0
)

            sort
(
a
,
 lo
,
 lo 
+
 count
[
0
]
 

 
1
,
 d
+
1
,
 aux
);

        
for
 
(
int
 r 
=
 
0
;
 r 
<  R ;  r ++ )              if   ( count [ r + 1 ]   >
 count
[
r
])

                sort
(
a
,
 lo 
+
 count
[
r
],
 lo 
+
 count
[
r
+
1
]
 

 
1
,
 d
+
1
,
 aux
);

    
}

    
// TODO: insertion sort a[lo..hi], starting at dth character

    
private
 
static
 
void
 insertion
(
int
[]
 a
,
 
int
 lo
,
 
int
 hi
,
 
int
 d
)
 
{

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 a
[
j
]
 
<  a [ j - 1 ];  j -- )                 exch ( a ,  j ,  j - 1 );      }      // exchange a[i] and a[j]      private   static   void  exch ( int []  a ,   int  i ,   int  j )   {          int  temp  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  temp ;      }      /**      * Reads in a sequence of extended ASCII strings from standard input;      * MSD radix sorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          int  n  =  a . length ;         sort ( a );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Multiway.java edu/princeton/cs/algs4/Multiway.java /******************************************************************************  *  Compilation:  javac Multiway.java  *  Execution:    java Multiway input1.txt input2.txt input3.txt ...  *  Dependencies: IndexMinPQ.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/24pq/m1.txt  *                https://algs4.cs.princeton.edu/24pq/m2.txt  *                https://algs4.cs.princeton.edu/24pq/m3.txt  *   *  Merges together the sorted input stream given as command-line arguments  *  into a single sorted output stream on standard output.  *  *  % more m1.txt   *  A B C F G I I Z  *  *  % more m2.txt   *  B D H P Q Q  *   *  % more m3.txt   *  A B E F J N  *  *  % java Multiway m1.txt m2.txt m3.txt   *  A A B B B C D E F F G H I I J N P Q Q Z   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Multiway} class provides a client for reading in several  *  sorted text files and merging them together into a single sorted  *  text stream.  *  This implementation uses a { @link  IndexMinPQ} to perform the multiway  *  merge.   *  

 *  For additional documentation, see Section 2.4

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Multiway
 
{
 

    
// This class should not be instantiated.

    
private
 
Multiway
()
 
{
 
}

    
// merge together the sorted input streams and write the sorted result to standard output

    
private
 
static
 
void
 merge
(
In
[]
 streams
)
 
{

        
int
 n 
=
 streams
.
length
;

        
IndexMinPQ
< String >
 pq 
=
 
new
 
IndexMinPQ
< String >
(
n
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )              if   ( ! streams [ i ]. isEmpty ())                 pq . insert ( i ,  streams [ i ]. readString ());          // Extract and print min and read next from its stream.           while   ( ! pq . isEmpty ())   {              StdOut . print ( pq . minKey ()   +   " " );              int  i  =  pq . delMin ();              if   ( ! streams [ i ]. isEmpty ())                 pq . insert ( i ,  streams [ i ]. readString ());          }          StdOut . println ();      }      /**      *  Reads sorted text files specified as command-line arguments;      *  merges them together into a sorted output; and writes      *  the results to standard output.      *  Note: this client does not check that the input files are sorted.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  n  =  args . length ;          In []  streams  =   new   In [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             streams [ i ]   =   new   In ( args [ i ]);         merge ( streams );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/MultiwayMinPQ.java edu/princeton/cs/algs4/MultiwayMinPQ.java /******************************************************************************  *  Compilation: javac MultiwayMinPQ.java     *  Execution:  *    *  A multiway heap.  *    ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . Comparator ; import  java . util . NoSuchElementException ; /**  *  The MultiwayMinPQ class represents a priority queue of generic keys.  *  It supports the usual insert and delete-the-minimum operations.  *  It also supports methods for peeking at the minimum key,  *  testing if the priority queue is empty, and iterating through  *  the keys.  *  It is possible to build the priority queue using a Comparator.  *  If not, the natural order relation between the keys will be used.  *    *  This implementation uses a multiway heap.  *  For simplified notations, logarithm in base d will be referred as log-d  *  The delete-the-minimum operation takes time proportional to d*log-d(n)  *  The insert takes time proportional to log-d(n)  *  The is-empty, min-key and size operations take constant time.  *  Constructor takes time proportional to the specified capacity.  *  *   @author  Tristan Claverie  */ public   class   MultiwayMinPQ < Key >
 
implements
 
Iterable
< Key >
 
{

    
private
 
final
 
int
 d
;
                
//Dimension of the heap

    
private
 
int
 n
;
                      
//Number of keys currently in the heap

    
private
 
int
 order
;
                  
//Number of levels of the tree

    
private
 
Key
[]
 keys
;
                 
//Array of keys

    
private
 
final
 
Comparator
< Key >
 comp
;
 
//Comparator over the keys

    

    

    
/**

     * Initializes an empty priority queue

     * Worst case is O(d)

     *

     * 
@param
  d dimension of the heap

     * 
@throws
 java.lang.IllegalArgumentException if {
@code
 d < 2}      */      public   MultiwayMinPQ ( int  d )   {          if   ( d  <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  d ;         order  =   1 ;         keys  =   ( Key [])   new   Comparable [ d  <<   1 ];         comp  =   new   MyComparator ();      }           /**      * Initializes an empty priority queue      * Worst case is O(d)      *      *  @param   d dimension of the heap      *  @param   comparator a Comparator over the keys      *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}      */      public   MultiwayMinPQ ( Comparator < Key >
 comparator
,
 
int
 d
)
 
{

        
if
 
(

<   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  d ;         order  =   1 ;         keys  =   ( Key [])   new   Comparable [ d  <<   1 ];         comp  =  comparator ;      }           /**      * Initializes a priority queue with given indexes      * Worst case is O(n*log-d(n))      *      *  @param   d dimension of the heap      *  @param   a an array of keys      *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}      */      public   MultiwayMinPQ ( Key []  a ,   int  d )   {          if   ( d  <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  d ;         order  =   1 ;         keys  =   ( Key [])   new   Comparable [ d  <<   1 ];         comp  =   new   MyComparator ();          for   ( Key  key  :  a )  insert ( key );      }           /**      * Initializes a priority queue with given indexes      * Worst case is O(a*log-d(n))      *      *  @param   d dimension of the heap      *  @param   comparator a Comparator over the keys      *  @param   a an array of keys      *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}      */      public   MultiwayMinPQ ( Comparator < Key >
 comparator
,
 
Key
[]
 a
,
 
int
 d
)
 
{

        
if
 
(

<   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );          this . d  =  d ;         order  =   1 ;         keys  =   ( Key [])   new   Comparable [ d  <<   1 ];         comp  =  comparator ;          for   ( Key  key  :  a )  insert ( key );      }          /**      * Whether the priority queue is empty      * Worst case is O(1)      *  @return  true if the priority queue is empty, false if not      */      public   boolean  isEmpty ()   {          return  n  ==   0 ;      }      /**      * Number of elements currently on the priority queue      * Worst case is O(1)      *  @return  the number of elements on the priority queue      */      public   int  size ()   {          return  n ;      }      /**      * Puts a Key on the priority queue      * Worst case is O(log-d(n))      *  @param  key a Key      */      public   void  insert ( Key  key )   {         keys [ n + d ]   =  key ;         swim ( n ++ );          if   ( n  ==  keys . length - d )   {             resize ( getN ( order + 1 ) + d );             order ++ ;          }      }      /**      * Gets the minimum key currently in the queue      * Worst case is O(1)      *  @throws  java.util.NoSuchElementException if the priority queue is empty      *  @return  the minimum key currently in the priority queue      */      public   Key  minKey ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );          return  keys [ d ];      }      /**      * Deletes the minimum key      * Worst case is O(d*log-d(n))      *  @throws  java.util.NoSuchElementException if the priority queue is empty      *  @return  the minimum key      */      public   Key  delMin ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );         exch ( 0 ,   -- n );         sink ( 0 );          Key  min  =  keys [ n + d ];         keys [ n + d ]   =   null ;          int  number  =  getN ( order - 2 );          if ( order  >
 
1
 
&&
 n 
==
 number
)
  
{

            resize
(
number
+
(
int
)
Math
.
pow
(
d
,
 order

1
)
+
d
);

            order

;

        
}

        
return
 min
;

    
}

    

    
/***************************

     * General helper functions

     **************************/

    

    
//Compares two keys

    
private
 
boolean
 greater
(
int
 x
,
 
int
 y
)
 
{

        
int
 i 
=
 x
+
d
,
 j 
=
 y
+
d
;

        
if
 
(
keys
[
i
]
 
==
 
null
)
 
return
 
false
;

        
if
 
(
keys
[
j
]
 
==
 
null
)
 
return
 
true
;

        
return
 comp
.
compare
(
keys
[
i
],
 keys
[
j
])
 
>
 
0
;

    
}

    

    
//Exchanges the position of two keys

    
private
 
void
 exch
(
int
 x
,
 
int
 y
)
 
{

        
int
 i 
=
 x
+
d
,
 j 
=
 y
+
d
;

        
Key
 swap 
=
 keys
[
i
];

        keys
[
i
]
 
=
 keys
[
j
];

        keys
[
j
]
 
=
 swap
;

    
}

    

    
//Gets the maximum number of keys in the heap, given the number of levels of the tree

    
private
 
int
 getN
(
int
 order
)
 
{

        
return
 
(
1

((
int
)
Math
.
pow
(
d
,
 order
+
1
)))
/
(
1

d
);

    
}

    

    
/***************************

     * Functions for moving upward or downward

     **************************/

    

    
//Moves upward

    
private
 
void
 swim
(
int
 i
)
 
{

        
if
 
(

>
 
0
 
&&
 greater
((
i

1
)
/
d
,
 i
))
 
{

            exch
(
i
,
 
(
i

1
)
/
d
);

            swim
((
i

1
)
/
d
);

        
}

    
}

    

    
//Moves downward

    
private
 
void
 sink
(
int
 i
)
 
{

        
int
 child 
=
 d
*
i
+
1
;

        
if
 
(
child 
>=
 n
)
 
return
;

        
int
 min 
=
 minChild
(
i
);

        
while
 
(
min 
<  n  &&  greater ( i ,  min ))   {             exch ( i ,  min );             i  =  min ;             min  =  minChild ( i );          }      }           /***************************      * Deletes the minimum child      **************************/           //Return the minimum child of i      private   int  minChild ( int  i )   {          int  loBound  =  d * i + 1 ,  hiBound  =  d * i + d ;          int  min  =  loBound ;          for   ( int  cur  =  loBound ;  cur  <=  hiBound ;  cur ++ )   {              if   ( cur  <  n  &&  greater ( min ,  cur ))  min  =  cur ;          }          return  min ;      }           /***************************      * Resize the priority queue      **************************/           //Resizes the array containing the keys      //If the heap is full, it adds one floor      //If the heap has two floors empty, it removes one      private   void  resize ( int  N )   {          Key []  array  =   ( Key [])   new   Comparable [ N ];          for   ( int  i  =   0 ;  i  <   Math . min ( keys . length ,  array . length );  i ++ )   {             array [ i ]   =  keys [ i ];             keys [ i ]   =   null ;          }         keys  =  array ;      }           /***************************      * Iterator      **************************/           /**      * Gets an Iterator over the keys in the priority queue in ascending order      * The Iterator does not implement the remove() method      * iterator() : Worst case is O(n)      * next() :     Worst case is O(d*log-d(n))      * hasNext() :  Worst case is O(1)      *  @return  an Iterator over the keys in the priority queue in ascending order      */           public   Iterator < Key >
 iterator
()
 
{

        
return
 
new
 
MyIterator
();

    
}

    

    
//Constructs an Iterator over the keys in linear time

    
private
 
class
 
MyIterator
 
implements
 
Iterator
< Key >
 
{

        
MultiwayMinPQ
< Key >
 data
;

        

        
public
 
MyIterator
()
 
{

            data 
=
 
new
 
MultiwayMinPQ
< Key >
(
comp
,
 d
);

            data
.
keys 
=
 
(
Key
[])
 
new
 
Comparable
[
keys
.
length
];

            data
.

=
 n
;

            
for
 
(
int
 i 
=
 
0
;
 i 
<  keys . length ;  i ++ )   {                 data . keys [ i ]   =  keys [ i ];              }          }          public   boolean  hasNext ()   {              return   ! data . isEmpty ();          }                   public   Key  next ()   {                          if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  data . delMin ();          }                   public   void  remove ()   {              throw   new   UnsupportedOperationException ();          }      }           /***************************      * Comparator      **************************/           //default Comparator      private   class   MyComparator   implements   Comparator < Key >
 
{

        @
Override

        
public
 
int
 compare
(
Key
 key1
,
 
Key
 key2
)
 
{

            
return
 
((
Comparable
< Key >
)
 key1
).
compareTo
(
key2
);

        
}

    
}

    

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/NFA.java
edu/princeton/cs/algs4/NFA.java
/******************************************************************************

 *  Compilation:  javac NFA.java

 *  Execution:    java NFA regexp text

 *  Dependencies: Stack.java Bag.java Digraph.java DirectedDFS.java

 *

 *  % java NFA “(A*B|AC)D” AAAABD

 *  true

 *

 *  % java NFA “(A*B|AC)D” AAAAC

 *  false

 *

 *  % java NFA “(a|(bc)*d)*” abcbcd

 *  true

 *

 *  % java NFA “(a|(bc)*d)*” abcbcbcdaaaabcbcdaaaddd

 *  true

 *

 *  Remarks

 *  ———–

 *  The following features are not supported:

 *    – The + operator

 *    – Multiway or

 *    – Metacharacters in the text

 *    – Character classes.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 NFA} class provides a data type for creating a

 *  nondeterministic finite state automaton (NFA) from a regular

 *  expression and testing whether a given string is matched by that regular

 *  expression.

 *  It supports the following operations: concatenation,

 *  closurebinary or, and parentheses.

 *  It does not support mutiway orcharacter classes,

 *  metacharacters (either in the text or pattern),

 *  capturing capabilitiesgreedy or relucantant

 *  modifiers, and other features in industrial-strength implementations

 *  such as {
@link
 java.util.regex.Pattern} and {
@link
 java.util.regex.Matcher}.

 *  

 *  This implementation builds the NFA using a digraph and a stack

 *  and simulates the NFA using digraph search (see the textbook for details).

 *  The constructor takes time proportional to m, where m

 *  is the number of characters in the regular expression.

 *  The recognizes method takes time proportional to m n,

 *  where n is the number of characters in the text.

 *  

 *  For additional documentation,

 *  see Section 5.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 NFA 
{
 

    
private
 
Digraph
 graph
;
     
// digraph of epsilon transitions

    
private
 
String
 regexp
;
     
// regular expression

    
private
 
final
 
int
 m
;
       
// number of characters in regular expression

    
/**

     * Initializes the NFA from the specified regular expression.

     *

     * 
@param
  regexp the regular expression

     */

    
public
 NFA
(
String
 regexp
)
 
{

        
this
.
regexp 
=
 regexp
;

        m 
=
 regexp
.
length
();

        
Stack
< Integer >
 ops 
=
 
new
 
Stack
< Integer >
();
 

        graph 
=
 
new
 
Digraph
(
m
+
1
);
 

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {                int  lp  =  i ;                if   ( regexp . charAt ( i )   ==   '('   ||  regexp . charAt ( i )   ==   '|' )                   ops . push ( i );                else   if   ( regexp . charAt ( i )   ==   ')' )   {                  int  or  =  ops . pop ();                    // 2-way or operator                  if   ( regexp . charAt ( or )   ==   '|' )   {                       lp  =  ops . pop ();                     graph . addEdge ( lp ,  or + 1 );                     graph . addEdge ( or ,  i );                  }                  else   if   ( regexp . charAt ( or )   ==   '(' )                     lp  =  or ;                  else   assert   false ;              }                // closure operator (uses 1-character lookahead)              if   ( i  <  m - 1   &&  regexp . charAt ( i + 1 )   ==   '*' )   {                   graph . addEdge ( lp ,  i + 1 );                   graph . addEdge ( i + 1 ,  lp );                }                if   ( regexp . charAt ( i )   ==   '('   ||  regexp . charAt ( i )   ==   '*'   ||  regexp . charAt ( i )   ==   ')' )                   graph . addEdge ( i ,  i + 1 );          }          if   ( ops . size ()   !=   0 )              throw   new   IllegalArgumentException ( "Invalid regular expression" );      }        /**      * Returns true if the text is matched by the regular expression.      *       *  @param   txt the text      *  @return  { @code  true} if the text is matched by the regular expression,      *         { @code  false} otherwise      */      public   boolean  recognizes ( String  txt )   {          DirectedDFS  dfs  =   new   DirectedDFS ( graph ,   0 );          Bag < Integer >
 pc 
=
 
new
 
Bag
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  graph . V ();  v ++ )              if   ( dfs . marked ( v ))  pc . add ( v );          // Compute possible NFA states for txt[i+1]          for   ( int  i  =   0 ;  i  <  txt . length ();  i ++ )   {              if   ( txt . charAt ( i )   ==   '*'   ||  txt . charAt ( i )   ==   '|'   ||  txt . charAt ( i )   ==   '('   ||  txt . charAt ( i )   ==   ')' )                  throw   new   IllegalArgumentException ( "text contains the metacharacter '"   +  txt . charAt ( i )   +   "'" );              Bag < Integer >
 match 
=
 
new
 
Bag
< Integer >
();

            
for
 
(
int
 v 
:
 pc
)
 
{

                
if
 
(

==
 m
)
 
continue
;

                
if
 
((
regexp
.
charAt
(
v
)
 
==
 txt
.
charAt
(
i
))
 
||
 regexp
.
charAt
(
v
)
 
==
 
‘.’
)

                    match
.
add
(
v
+
1
);
 

            
}

            dfs 
=
 
new
 
DirectedDFS
(
graph
,
 match
);
 

            pc 
=
 
new
 
Bag
< Integer >
();

            
for
 
(
int
 v 
=
 
0
;
 v 
<  graph . V ();  v ++ )                  if   ( dfs . marked ( v ))  pc . add ( v );              // optimization if no states reachable              if   ( pc . size ()   ==   0 )   return   false ;          }          // check for accept state          for   ( int  v  :  pc )              if   ( v  ==  m )   return   true ;          return   false ;      }      /**      * Unit tests the { @code  NFA} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String  regexp  =   "("   +  args [ 0 ]   +   ")" ;          String  txt  =  args [ 1 ];         NFA nfa  =   new  NFA ( regexp );          StdOut . println ( nfa . recognizes ( txt ));      } }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/NonrecursiveDFS.java edu/princeton/cs/algs4/NonrecursiveDFS.java /******************************************************************************  *  Compilation:  javac NonrecursiveDFS.java  *  Execution:    java NonrecursiveDFS graph.txt s  *  Dependencies: Graph.java Queue.java Stack.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt  *                https://algs4.cs.princeton.edu/41graph/tinyG.txt  *                https://algs4.cs.princeton.edu/41graph/mediumG.txt  *  *  Run nonrecurisve depth-first search on an undirected graph.  *  Runs in O(E + V) time using O(V) extra space.  *  *  Explores the vertices in exactly the same order as DepthFirstSearch.java.  *  *  %  java Graph tinyG.txt  *  13 vertices, 13 edges   *  0: 6 2 1 5   *  1: 0   *  2: 0   *  3: 5 4   *  4: 5 6 3   *  5: 3 4 0   *  6: 0 4   *  7: 8   *  8: 7   *  9: 11 10 12   *  10: 9   *  11: 9 12   *  12: 11 9   *  *  % java NonrecursiveDFS tinyG.txt 0  *  0 1 2 3 4 5 6   *  * % java NonrecursiveDFS tinyG.txt 9  * 9 10 11 12   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; /**  *  The { @code  NonrecursiveDFS} class represents a data type for finding  *  the vertices connected to a source vertex s in the undirected

 *  graph.

 *  

 *  This implementation uses a nonrecursive version of depth-first search

 *  with an explicit stack.

 *  See {
@link
 DepthFirstSearch} for the classic recursive version.

 *  The constructor takes Θ(V + E) time in the worst

 *  case, where V is the number of vertices and E is the

 *  number of edges.

 *  The {
@link
 #marked(int)} instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the graph). 

 *  

 *  For additional documentation,

 *  see Section 4.1   

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
NonrecursiveDFS
 
{

    
private
 
boolean
[]
 marked
;
  
// marked[v] = is there an s-v path?

    
/**

     * Computes the vertices connected to the source vertex {
@code
 s} in the graph {
@code
 G}.

     * 
@param
 G the graph

     * 
@param
 s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   NonrecursiveDFS ( Graph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         validateVertex ( s );          // to be able to iterate over each adjacency list, keeping track of which          // vertex in each adjacency list needs to be explored next          Iterator < Integer >
[]
 adj 
=
 
(
Iterator
< Integer >
[])
 
new
 
Iterator
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =  G . adj ( v ). iterator ();          // depth-first search using an explicit stack          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        marked
[
s
]
 
=
 
true
;

        stack
.
push
(
s
);

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
peek
();

            
if
 
(
adj
[
v
].
hasNext
())
 
{

                
int
 w 
=
 adj
[
v
].
next
();

                
// StdOut.printf(“check %d\n”, w);

                
if
 
(
!
marked
[
w
])
 
{

                    
// discovered vertex w for the first time

                    marked
[
w
]
 
=
 
true
;

                    
// edgeTo[w] = v;

                    stack
.
push
(
w
);

                    
// StdOut.printf(“dfs(%d)\n”, w);

                
}

            
}

            
else
 
{

                
// StdOut.printf(“%d done\n”, v);

                stack
.
pop
();

            
}

        
}

    
}

    
/**

     * Is vertex {
@code
 v} connected to the source vertex {
@code
 s}?

     * 
@param
 v the vertex

     * 
@return
 {
@code
 true} if vertex {
@code
 v} is connected to the source vertex {
@code
 s},

     *    and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   boolean  marked ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 NonrecursiveDFS} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Graph
 G 
=
 
new
 
Graph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
NonrecursiveDFS
 dfs 
=
 
new
 
NonrecursiveDFS
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( dfs . marked ( v ))                  StdOut . print ( v  +   " " );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java /******************************************************************************  *  Compilation:  javac NonrecursiveDirectedDFS.java  *  Execution:    java NonrecursiveDirectedDFS digraph.txt s  *  Dependencies: Digraph.java Queue.java Stack.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt  *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt  *  *  Run nonrecurisve depth-first search on an directed graph.  *  Runs in O(E + V) time.  *  *  Explores the vertices in exactly the same order as DirectedDFS.java.  *  *  *  % java NonrecursiveDirectedDFS tinyDG.txt 1  *  1  *  *  % java NonrecursiveDirectedDFS tinyDG.txt 2  *  0 1 2 3 4 5  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; /**  *  The { @code  NonrecursiveDirectedDFS} class represents a data type for finding  *  the vertices reachable from a source vertex s in the digraph.

 *  

 *  This implementation uses a nonrecursive version of depth-first search

 *  with an explicit stack.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
NonrecursiveDirectedDFS
 
{

    
private
 
boolean
[]
 marked
;
  
// marked[v] = is there an s->v path?

    
/**

     * Computes the vertices reachable from the source vertex {
@code
 s} in the digraph {
@code
 G}.

     * 
@param
  G the digraph

     * 
@param
  s the source vertex

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= s < V}      */      public   NonrecursiveDirectedDFS ( Digraph  G ,   int  s )   {         marked  =   new   boolean [ G . V ()];         validateVertex ( s );          // to be able to iterate over each adjacency list, keeping track of which          // vertex in each adjacency list needs to be explored next          Iterator < Integer >
[]
 adj 
=
 
(
Iterator
< Integer >
[])
 
new
 
Iterator
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             adj [ v ]   =  G . adj ( v ). iterator ();          // depth-first search using an explicit stack          Stack < Integer >
 stack 
=
 
new
 
Stack
< Integer >
();

        marked
[
s
]
 
=
 
true
;

        stack
.
push
(
s
);

        
while
 
(
!
stack
.
isEmpty
())
 
{

            
int
 v 
=
 stack
.
peek
();

            
if
 
(
adj
[
v
].
hasNext
())
 
{

                
int
 w 
=
 adj
[
v
].
next
();

                
// StdOut.printf(“check %d\n”, w);

                
if
 
(
!
marked
[
w
])
 
{

                    
// discovered vertex w for the first time

                    marked
[
w
]
 
=
 
true
;

                    
// edgeTo[w] = v;

                    stack
.
push
(
w
);

                    
// StdOut.printf(“dfs(%d)\n”, w);

                
}

            
}

            
else
 
{

                
// StdOut.printf(“%d done\n”, v);

                stack
.
pop
();

            
}

        
}

    
}

    
/**

     * Is vertex {
@code
 v} reachable from the source vertex {
@code
 s}?

     * 
@param
  v the vertex

     * 
@return
 {
@code
 true} if vertex {
@code
 v} is reachable from the source vertex {
@code
 s},

     *         and {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   boolean  marked ( int  v )   {         validateVertex ( v );          return  marked [ v ];      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 NonrecursiveDirectedDFS} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
int
 s 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
NonrecursiveDirectedDFS
 dfs 
=
 
new
 
NonrecursiveDirectedDFS
(
G
,
 s
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( dfs . marked ( v ))                  StdOut . print ( v  +   " " );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Out.java edu/princeton/cs/algs4/Out.java /******************************************************************************  *  Compilation:  javac Out.java  *  Execution:    java Out  *  Dependencies: none  *  *  Writes data of various types to: stdout, file, or socket.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . io . FileOutputStream ; import  java . io . IOException ; import  java . io . OutputStream ; import  java . io . OutputStreamWriter ; import  java . io . PrintWriter ; import  java . net . Socket ; import  java . util . Locale ; /**  *  This class provides methods for writing strings and numbers to  *  various output streams, including standard output, file, and sockets.  *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Out
 
{

    
// force Unicode UTF-8 encoding; otherwise it’s system dependent

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with In

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
private
 
PrintWriter
 out
;

   
/**

     * Initializes an output stream from a {
@link
 OutputStream}.

     *

     * 
@param
  os the {
@code
 OutputStream}

     */

    
public
 
Out
(
OutputStream
 os
)
 
{

        
try
 
{

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes an output stream from standard output.

     */

    
public
 
Out
()
 
{

        
this
(
System
.
out
);

    
}

   
/**

     * Initializes an output stream from a socket.

     *

     * 
@param
  socket the socket

     */

    
public
 
Out
(
Socket
 socket
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 socket
.
getOutputStream
();

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes an output stream from a file.

     *

     * 
@param
  filename the name of the file

     */

    
public
 
Out
(
String
 filename
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 
new
 
FileOutputStream
(
filename
);

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Closes the output stream.

     */

    
public
 
void
 close
()
 
{

        out
.
close
();

    
}

   
/**

     * Terminates the current line by printing the line-separator string.

     */

    
public
 
void
 println
()
 
{

        out
.
println
();

    
}

   
/**

     * Prints an object to this output stream and then terminates the line.

     *

     * 
@param
 x the object to print

     */

    
public
 
void
 println
(
Object
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a boolean to this output stream and then terminates the line.

     *

     * 
@param
 x the boolean to print

     */

    
public
 
void
 println
(
boolean
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a character to this output stream and then terminates the line.

     *

     * 
@param
 x the character to print

     */

    
public
 
void
 println
(
char
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a double to this output stream and then terminates the line.

     *

     * 
@param
 x the double to print

     */

    
public
 
void
 println
(
double
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a float to this output stream and then terminates the line.

     *

     * 
@param
 x the float to print

     */

    
public
 
void
 println
(
float
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to this output stream and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
void
 println
(
int
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a long to this output stream and then terminates the line.

     *

     * 
@param
 x the long to print

     */

    
public
 
void
 println
(
long
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a byte to this output stream and then terminates the line.

     * 

     * To write binary data, see {
@link
 BinaryOut}.

     *

     * 
@param
 x the byte to print

     */

    
public
 
void
 println
(
byte
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Flushes this output stream.

     */

    
public
 
void
 print
()
 
{

        out
.
flush
();

    
}

   
/**

     * Prints an object to this output stream and flushes this output stream.

     * 

     * 
@param
 x the object to print

     */

    
public
 
void
 print
(
Object
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a boolean to this output stream and flushes this output stream.

     * 

     * 
@param
 x the boolean to print

     */

    
public
 
void
 print
(
boolean
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a character to this output stream and flushes this output stream.

     * 

     * 
@param
 x the character to print

     */

    
public
 
void
 print
(
char
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a double to this output stream and flushes this output stream.

     * 

     * 
@param
 x the double to print

     */

    
public
 
void
 print
(
double
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a float to this output stream and flushes this output stream.

     * 

     * 
@param
 x the float to print

     */

    
public
 
void
 print
(
float
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints an integer to this output stream and flushes this output stream.

     * 

     * 
@param
 x the integer to print

     */

    
public
 
void
 print
(
int
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a long integer to this output stream and flushes this output stream.

     * 

     * 
@param
 x the long integer to print

     */

    
public
 
void
 print
(
long
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a byte to this output stream and flushes this output stream.

     * 

     * 
@param
 x the byte to print

     */

    
public
 
void
 print
(
byte
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to this output stream, using the specified format

     * string and arguments, and then flushes this output stream.

     *

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
void
 printf
(
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
LOCALE
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to this output stream, using the specified

     * locale, format string, and arguments, and then flushes this output stream.

     *

     * 
@param
 locale the locale

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
void
 printf
(
Locale
 locale
,
 
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
locale
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * A test client.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Out
 out
;

        
// write to stdout

        out 
=
 
new
 
Out
();

        out
.
println
(
“Test 1”
);

        out
.
close
();

        
// write to a file

        out 
=
 
new
 
Out
(
“test.txt”
);

        out
.
println
(
“Test 2”
);

        out
.
close
();

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Particle.java
edu/princeton/cs/algs4/Particle.java
/******************************************************************************

 *  Compilation:  javac Particle.java

 *  Execution:    none

 *  Dependencies: StdDraw.java

 *      

 *  A particle moving in the unit box with a given position, velocity,

 *  radius, and mass.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
awt
.
Color
;

/**

 *  The {
@code
 Particle} class represents a particle moving in the unit box,

 *  with a given position, velocity, radius, and mass. Methods are provided

 *  for moving the particle and for predicting and resolvling elastic

 *  collisions with vertical walls, horizontal walls, and other particles.

 *  This data type is mutable because the position and velocity change.

 *  

 *  For additional documentation, 

 *  see Section 6.1 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Particle
 
{

    
private
 
static
 
final
 
double
 INFINITY 
=
 
Double
.
POSITIVE_INFINITY
;

    
private
 
double
 rx
,
 ry
;
        
// position

    
private
 
double
 vx
,
 vy
;
        
// velocity

    
private
 
int
 count
;
            
// number of collisions so far

    
private
 
final
 
double
 radius
;
  
// radius

    
private
 
final
 
double
 mass
;
    
// mass

    
private
 
final
 
Color
 color
;
    
// color

    
/**

     * Initializes a particle with the specified position, velocity, radius, mass, and color.

     *

     * 
@param
  rx x-coordinate of position

     * 
@param
  ry y-coordinate of position

     * 
@param
  vx x-coordinate of velocity

     * 
@param
  vy y-coordinate of velocity

     * 
@param
  radius the radius

     * 
@param
  mass the mass

     * 
@param
  color the color

     */

    
public
 
Particle
(
double
 rx
,
 
double
 ry
,
 
double
 vx
,
 
double
 vy
,
 
double
 radius
,
 
double
 mass
,
 
Color
 color
)
 
{

        
this
.
vx 
=
 vx
;

        
this
.
vy 
=
 vy
;

        
this
.
rx 
=
 rx
;

        
this
.
ry 
=
 ry
;

        
this
.
radius 
=
 radius
;

        
this
.
mass   
=
 mass
;

        
this
.
color  
=
 color
;

    
}

         

    
/**

     * Initializes a particle with a random position and velocity.

     * The position is uniform in the unit box; the velocity in

     * either direciton is chosen uniformly at random.

     */

    
public
 
Particle
()
 
{

        rx     
=
 
StdRandom
.
uniform
(
0.0
,
 
1.0
);

        ry     
=
 
StdRandom
.
uniform
(
0.0
,
 
1.0
);

        vx     
=
 
StdRandom
.
uniform
(

0.005
,
 
0.005
);

        vy     
=
 
StdRandom
.
uniform
(

0.005
,
 
0.005
);

        radius 
=
 
0.02
;

        mass   
=
 
0.5
;

        color  
=
 
Color
.
BLACK
;

    
}

    
/**

     * Moves this particle in a straight line (based on its velocity)

     * for the specified amount of time.

     *

     * 
@param
  dt the amount of time

     */

    
public
 
void
 move
(
double
 dt
)
 
{

        rx 
+=
 vx 
*
 dt
;

        ry 
+=
 vy 
*
 dt
;

    
}

    
/**

     * Draws this particle to standard draw.

     */

    
public
 
void
 draw
()
 
{

        
StdDraw
.
setPenColor
(
color
);

        
StdDraw
.
filledCircle
(
rx
,
 ry
,
 radius
);

    
}

    
/**

     * Returns the number of collisions involving this particle with

     * vertical walls, horizontal walls, or other particles.

     * This is equal to the number of calls to {
@link
 #bounceOff},

     * {
@link
 #bounceOffVerticalWall}, and

     * {
@link
 #bounceOffHorizontalWall}.

     *

     * 
@return
 the number of collisions involving this particle with

     *         vertical walls, horizontal walls, or other particles

     */

    
public
 
int
 count
()
 
{

        
return
 count
;

    
}

    
/**

     * Returns the amount of time for this particle to collide with the specified

     * particle, assuming no interening collisions.

     *

     * 
@param
  that the other particle

     * 
@return
 the amount of time for this particle to collide with the specified

     *         particle, assuming no interening collisions; 

     *         {
@code
 Double.POSITIVE_INFINITY} if the particles will not collide

     */

    
public
 
double
 timeToHit
(
Particle
 that
)
 
{

        
if
 
(
this
 
==
 that
)
 
return
 INFINITY
;

        
double
 dx  
=
 that
.
rx 

 
this
.
rx
;

        
double
 dy  
=
 that
.
ry 

 
this
.
ry
;

        
double
 dvx 
=
 that
.
vx 

 
this
.
vx
;

        
double
 dvy 
=
 that
.
vy 

 
this
.
vy
;

        
double
 dvdr 
=
 dx
*
dvx 
+
 dy
*
dvy
;

        
if
 
(
dvdr 
>
 
0
)
 
return
 INFINITY
;

        
double
 dvdv 
=
 dvx
*
dvx 
+
 dvy
*
dvy
;

        
if
 
(
dvdv 
==
 
0
)
 
return
 INFINITY
;

        
double
 drdr 
=
 dx
*
dx 
+
 dy
*
dy
;

        
double
 sigma 
=
 
this
.
radius 
+
 that
.
radius
;

        
double
 d 
=
 
(
dvdr
*
dvdr
)
 

 dvdv 
*
 
(
drdr 

 sigma
*
sigma
);

        
// if (drdr < sigma*sigma) StdOut.println("overlapping particles");          if   ( d  <   0 )   return  INFINITY ;          return   - ( dvdr  +   Math . sqrt ( d ))   /  dvdv ;      }      /**      * Returns the amount of time for this particle to collide with a vertical      * wall, assuming no interening collisions.      *      *  @return  the amount of time for this particle to collide with a vertical wall,      *         assuming no interening collisions;       *         { @code  Double.POSITIVE_INFINITY} if the particle will not collide      *         with a vertical wall      */      public   double  timeToHitVerticalWall ()   {          if        ( vx  >
 
0
)
 
return
 
(
1.0
 

 rx 

 radius
)
 
/
 vx
;

        
else
 
if
 
(
vx 
<   0 )   return   ( radius  -  rx )   /  vx ;             else               return  INFINITY ;      }      /**      * Returns the amount of time for this particle to collide with a horizontal      * wall, assuming no interening collisions.      *      *  @return  the amount of time for this particle to collide with a horizontal wall,      *         assuming no interening collisions;       *         { @code  Double.POSITIVE_INFINITY} if the particle will not collide      *         with a horizontal wall      */      public   double  timeToHitHorizontalWall ()   {          if        ( vy  >
 
0
)
 
return
 
(
1.0
 

 ry 

 radius
)
 
/
 vy
;

        
else
 
if
 
(
vy 
<   0 )   return   ( radius  -  ry )   /  vy ;          else               return  INFINITY ;      }      /**      * Updates the velocities of this particle and the specified particle according      * to the laws of elastic collision. Assumes that the particles are colliding      * at this instant.      *      *  @param   that the other particle      */      public   void  bounceOff ( Particle  that )   {          double  dx   =  that . rx  -   this . rx ;          double  dy   =  that . ry  -   this . ry ;          double  dvx  =  that . vx  -   this . vx ;          double  dvy  =  that . vy  -   this . vy ;          double  dvdr  =  dx * dvx  +  dy * dvy ;               // dv dot dr          double  dist  =   this . radius  +  that . radius ;     // distance between particle centers at collison          // magnitude of normal force          double  magnitude  =   2   *   this . mass  *  that . mass  *  dvdr  /   (( this . mass  +  that . mass )   *  dist );          // normal force, and in x and y directions          double  fx  =  magnitude  *  dx  /  dist ;          double  fy  =  magnitude  *  dy  /  dist ;          // update velocities according to normal force          this . vx  +=  fx  /   this . mass ;          this . vy  +=  fy  /   this . mass ;         that . vx  -=  fx  /  that . mass ;         that . vy  -=  fy  /  that . mass ;          // update collision counts          this . count ++ ;         that . count ++ ;      }      /**      * Updates the velocity of this particle upon collision with a vertical      * wall (by reflecting the velocity in the x-direction).

     * Assumes that the particle is colliding with a vertical wall at this instant.

     */

    
public
 
void
 bounceOffVerticalWall
()
 
{

        vx 
=
 

vx
;

        count
++
;

    
}

    
/**

     * Updates the velocity of this particle upon collision with a horizontal

     * wall (by reflecting the velocity in the y-direction).

     * Assumes that the particle is colliding with a horizontal wall at this instant.

     */

    
public
 
void
 bounceOffHorizontalWall
()
 
{

        vy 
=
 

vy
;

        count
++
;

    
}

    
/**

     * Returns the kinetic energy of this particle.

     * The kinetic energy is given by the formula 1/2 m v2,

     * where m is the mass of this particle and v is its velocity.

     *

     * 
@return
 the kinetic energy of this particle

     */

    
public
 
double
 kineticEnergy
()
 
{

        
return
 
0.5
 
*
 mass 
*
 
(
vx
*
vx 
+
 vy
*
vy
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/PatriciaSET.java
edu/princeton/cs/algs4/PatriciaSET.java
/******************************************************************************

 *  Compilation:  javac PatriciaSET.java

 *  Execution:    java PatriciaSET

 *  Dependencies: StdOut.java StdRandom.java Queue.java

 *  Data files:   n/a

 *

 *  A set implementation based on PATRICIA.

 *

 *  % java PatriciaSET 1000000 1

 *  Creating dataset (1000000 items)…

 *  Shuffling…

 *  Adding (1000000 items)…

 *  Iterating…

 *  1000000 items iterated

 *  Shuffling…

 *  Deleting (500000 items)…

 *  Iterating…

 *  500000 items iterated

 *  Checking…

 *  500000 items found and 500000 (deleted) items missing

 *  Deleting the rest (500000 items)…

 *  PASS 1 TESTS SUCCEEDED

 *  %

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

/**

 *  The {
@code
 PatriciaSET} class provides an implementation of an

 *  unordered set, with the restriction that the items (keys) are of class

 *  {
@link
 java.lang.String}. It supports the usual add,

 *  containsdeletesize, and is-empty

 *  methods. It also provides an iterator method for iterating over all

 *  the elements in the set.

 *  

 *  This unordered set class implements PATRICIA (Practical Algorithm to

 *  Retrieve Information Coded In Alphanumeric). In spite of the acronym, string

 *  keys are not limited to alphanumeric content. A key may possess any string

 *  value, with one exception: a zero-length string is not permitted.

 *  

 *  Unlike other generic set implementations that can accept a parameterized key

 *  type, this set class can only accommodate keys of class

 *  {
@link
 java.lang.String}. This unfortunate restriction stems from a

 *  limitation in Java. Although Java provides excellent support for generic

 *  programming, the current infrastructure somewhat limits generic collection

 *  implementations to those that employ comparison-based or hash-based methods.

 *  PATRICIA does not employ comparisons or hashing; instead, it relies on

 *  bit-test operations. Because Java does not furnish any generic abstractions

 *  (or implementations) for bit-testing the contents of an object, providing

 *  support for generic keys using PATRICIA does not seem practical.

 *  

 *  PATRICIA is a variation of a trie, and it is often classified as a

 *  space-optimized trie. In a classical trie, each level represents a

 *  subsequent digit in a key. In PATRICIA, nodes only exist to identify the

 *  digits (bits) that distinguish the individual keys within the trie. Because

 *  PATRICIA uses a radix of two, each node has only two children, like a binary

 *  tree. Also like a binary tree, the number of nodes, within the trie, equals

 *  the number of keys. Consequently, some classify PATRICIA as a tree.

 *  

 *  The analysis of PATRICIA is complicated. The theoretical wost-case

 *  performance for an addcontains, or delete

 *  operation is O(N), when N is less than

 *  W (where W is the length in bits of the

 *  longest key), and O(W), when N is greater

 *  than W. However, the worst case is unlikely to occur with

 *  typical use. The average (and usual) performance of PATRICIA is

 *  approximately ~lg N for each add,

 *  contains, or delete operation. Although this appears to

 *  put PATRICIA on the same footing as binary trees, this time complexity

 *  represents the number of single-bit test operations (under PATRICIA), and

 *  not full-key comparisons (as required by binary trees). After the single-bit

 *  tests conclude, PATRICIA requires just one full-key comparison to confirm

 *  the existence (or absence) of the key (per addcontains,

 *  or delete operation).

 *  

 *  In practice, decent implementations of PATRICIA can often outperform

 *  balanced binary trees, and even hash tables. Although this particular

 *  implementation performs well, the source code was written with an emphasis

 *  on clarity, and not performance. PATRICIA performs admirably when its

 *  bit-testing loops are well tuned. Consider using the source code as a guide,

 *  should you need to produce an optimized implementation, for anther key type,

 *  or in another programming language.

 *  

 *  Other resources for PATRICIA:

 *  Sedgewick, R. (1990) Algorithms in C, Addison-Wesley

 *  Knuth, D. (1973) The Art of Computer Programming, Addison-Wesley

 *

 *  
@author
 John Hentosh (based on an implementation by Robert Sedgewick)

 */

public
 
class
 
PatriciaSET
 
implements
 
Iterable
< String >
 
{

    
private
 
Node
 head
;

    
private
 
int
 count
;

    
/* An inner Node class specifies the objects that hold each key. The b

     * value indicates the relevant bit position.

     */

    
private
 
class
 
Node
 
{

        
private
 
Node
 left
,
 right
;

        
private
 
String
 key
;

        
private
 
int
 b
;

        
public
 
Node
(
String
 key
,
 
int
 b
)
 
{

            
this
.
key 
=
 key
;

            
this
.

=
 b
;

        
}

    
};

    
/**

     * Initializes an empty PATRICIA-based set.

     */

    
/* The constructor creates a head (sentinel) node that contains a

     * zero-length string.

     */

    
public
 
PatriciaSET
()
 
{

        head 
=
 
new
 
Node
(
“”
,
 
0
);

        head
.
left 
=
 head
;

        head
.
right 
=
 head
;

        count 
=
 
0
;

    
}

    
/**

     * Adds the key to the set if it is not already present.

     * 
@param
 key the key to add

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if {
@code
 key} is the empty string.

     */

    
public
 
void
 add
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called add(null)”
);

        
if
 
(
key
.
length
()
 
==
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“invalid key”
);

        
Node
 p
;

        
Node
 x 
=
 head
;

        
do
 
{

            p 
=
 x
;

            
if
 
(
safeBitTest
(
key
,
 x
.
b
))
 x 
=
 x
.
right
;

            
else
                       x 
=
 x
.
left
;

        
}
 
while
 
(
p
.

<  x . b );          if   ( ! x . key . equals ( key ))   {              int  b  =  firstDifferingBit ( x . key ,  key );             x  =  head ;              do   {                 p  =  x ;                  if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;                  else                        x  =  x . left ;              }   while   ( p . b  <  x . b  &&  x . b  <  b );              Node  t  =   new   Node ( key ,  b );              if   ( safeBitTest ( key ,  b ))   {                 t . left   =  x ;                 t . right  =  t ;              }              else   {                 t . left   =  t ;                 t . right  =  x ;              }              if   ( safeBitTest ( key ,  p . b ))  p . right  =  t ;              else                        p . left  =  t ;             count ++ ;          }      }      /**      * Does the set contain the given key?      *  @param  key the key      *  @return  { @code  true} if the set contains { @code  key} and      * { @code  false} otherwise      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      *  @throws  IllegalArgumentException if { @code  key} is the empty string.      */      public   boolean  contains ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called contains(null)" );          if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );          Node  p ;          Node  x  =  head ;          do   {             p  =  x ;              if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;              else                        x  =  x . left ;          }   while   ( p . b  <  x . b );          return  x . key . equals ( key );      }      /**      * Removes the key from the set if the key is present.      *  @param  key the key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      *  @throws  IllegalArgumentException if { @code  key} is the empty string.      */      public   void  delete ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called delete(null)" );          if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );          Node  g ;               // previous previous (grandparent)          Node  p  =  head ;        // previous (parent)          Node  x  =  head ;        // node to delete          do   {             g  =  p ;             p  =  x ;              if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;              else                        x  =  x . left ;          }   while   ( p . b  <  x . b );          if   ( x . key . equals ( key ))   {              Node  z ;              Node  y  =  head ;              do   {              // find the true parent (z) of x                 z  =  y ;                  if   ( safeBitTest ( key ,  y . b ))  y  =  y . right ;                  else                        y  =  y . left ;              }   while   ( y  !=  x );              if   ( x  ==  p )   {     // case 1: remove (leaf node) x                  Node  c ;       // child of x                  if   ( safeBitTest ( key ,  x . b ))  c  =  x . left ;                  else                        c  =  x . right ;                  if   ( safeBitTest ( key ,  z . b ))  z . right  =  c ;                  else                        z . left   =  c ;              }              else   {            // case 2: p replaces (internal node) x                  Node  c ;       // child of p                  if   ( safeBitTest ( key ,  p . b ))  c  =  p . left ;                  else                        c  =  p . right ;                  if   ( safeBitTest ( key ,  g . b ))  g . right  =  c ;                  else                        g . left   =  c ;                  if   ( safeBitTest ( key ,  z . b ))  z . right  =  p ;                  else                        z . left   =  p ;                 p . left  =  x . left ;                 p . right  =  x . right ;                 p . b  =  x . b ;              }             count -- ;          }      }      /**      * Is the set empty?      *  @return  { @code  true} if the set is empty, and { @code  false}      * otherwise      */      boolean  isEmpty ()   {          return  count  ==   0 ;      }      /**      * Returns the number of keys in the set.      *  @return  the number of keys in the set      */      int  size ()   {          return  count ;      }      /**      * Returns all of the keys in the set, as an iterator.      * To iterate over all of the keys in a set named { @code  set}, use the      * foreach notation: { @code  for (Key key : set)}.      *  @return  an iterator to all of the keys in the set      */      public   Iterator < String >
 iterator
()
 
{

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        
if
 
(
head
.
left  
!=
 head
)
 collect
(
head
.
left
,
  
0
,
 queue
);

        
if
 
(
head
.
right 
!=
 head
)
 collect
(
head
.
right
,
 
0
,
 queue
);

        
return
 queue
.
iterator
();

    
}

    
private
 
void
 collect
(
Node
 x
,
 
int
 b
,
 
Queue
< String >
 queue
)
 
{

        
if
 
(
x
.

>
 b
)
 
{

            collect
(
x
.
left
,
 x
.
b
,
 queue
);

            queue
.
enqueue
(
x
.
key
);

            collect
(
x
.
right
,
 x
.
b
,
 queue
);

        
}

    
}

    
/**

     * Returns a string representation of this set.

     * 
@return
 a string representation of this set, with the keys separated

     * by single spaces

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        
for
 
(
String
 key 
:
 
this
)
 s
.
append
(
key 
+
 
” ”
);

        
if
 
(
s
.
length
()
 
>
 
0
)
 s
.
deleteCharAt
(
s
.
length
()
 

 
1
);

        
return
 s
.
toString
();

    
}

    
/* The safeBitTest function logically appends a terminating sequence (when

     * required) to extend (logically) the string beyond its length.

     *

     * The inner loops of the get and put methods flow much better when they

     * are not concerned with the lengths of strings, so a trick is employed to

     * allow the get and put methods to view every string as an “infinite”

     * sequence of bits. Logically, every string gets a ‘\uffff’ character,

     * followed by an “infinite” sequence of ‘\u0000’ characters, appended to

     * the end.

     *

     * Note that the ‘\uffff’ character serves to mark the end of the string,

     * and it is necessary. Simply padding with ‘\u0000’ is insufficient to

     * make all unique Unicode strings “look” unique to the get and put methods

     * (because these methods do not regard string lengths).

     */

    
private
 
static
 
boolean
 safeBitTest
(
String
 key
,
 
int
 b
)
 
{

        
if
 
(

<  key . length ()   *   16 )        return  bitTest ( key ,  b )   !=   0 ;          if   ( b  >
 key
.
length
()
 
*
 
16
 
+
 
15
)
 
return
 
false
;
   
// padding

        
/* 16 bits of 0xffff */
         
return
 
true
;
    
// end marker

    
}

    
private
 
static
 
int
 bitTest
(
String
 key
,
 
int
 b
)
 
{

        
return
 
(
key
.
charAt
(

>>>
 
4
)
 
>>>
 
(

&
 
0xf
))
 
&
 
1
;

    
}

    
/* Like the safeBitTest function, the safeCharAt function makes every

     * string look like an “infinite” sequence of characters. Logically, every

     * string gets a ‘\uffff’ character, followed by an “infinite” sequence of

     * ‘\u0000’ characters, appended to the end.

     */

    
private
 
static
 
int
 safeCharAt
(
String
 key
,
 
int
 i
)
 
{

        
if
 
(

<  key . length ())   return  key . charAt ( i );          if   ( i  >
 key
.
length
())
 
return
 
0x0000
;
            
// padding

        
else
                  
return
 
0xffff
;
            
// end marker

    
}

    
/* For efficiency’s sake, the firstDifferingBit function compares entire

     * characters first, and then considers the individual bits (once it finds

     * two characters that do not match). Also, the least significant bits of

     * an individual character are examined first. There are many Unicode

     * alphabets where most (if not all) of the “action” occurs in the least

     * significant bits.

     *

     * Notice that the very first character comparison excludes the

     * least-significant bit. The firstDifferingBit function must never return

     * zero; otherwise, a node would become created as a child to the head

     * (sentinel) node that matches the bit-index value (zero) stored in the

     * head node. This would violate the invariant that bit-index values

     * increase as you descend into the trie.

     */

    
private
 
static
 
int
 firstDifferingBit
(
String
 k1
,
 
String
 k2
)
 
{

        
int
 i 
=
 
0
;

        
int
 c1 
=
 safeCharAt
(
k1
,
 
0
)
 
&
 
~
1
;

        
int
 c2 
=
 safeCharAt
(
k2
,
 
0
)
 
&
 
~
1
;

        
if
 
(
c1 
==
 c2
)
 
{

            i 
=
 
1
;

            
while
 
(
safeCharAt
(
k1
,
 i
)
 
==
 safeCharAt
(
k2
,
 i
))
 i
++
;

            c1 
=
 safeCharAt
(
k1
,
 i
);

            c2 
=
 safeCharAt
(
k2
,
 i
);

        
}

        
int
 b 
=
 
0
;

        
while
 
(((
c1 
>>>
 b
)
 
&
 
1
)
 
==
 
((
c2 
>>>
 b
)
 
&
 
1
))
 b
++
;

        
return
 i 
*
 
16
 
+
 b
;

    
}

    
/**

     * Unit tests the {
@code
 PatriciaSET} data type.

     * This test fixture runs a series of tests on a randomly generated dataset.

     * You may specify up to two integer parameters on the command line. The

     * first parameter indicates the size of the dataset. The second parameter

     * controls the number of passes (a new random dataset becomes generated at

     * the start of each pass).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
PatriciaSET
 set 
=
 
new
 
PatriciaSET
();

        
int
 limitItem 
=
 
1000000
;

        
int
 limitPass 
=
 
1
;

        
int
 countPass 
=
 
0
;

        
boolean
 ok 
=
 
true
;

        
if
 
(
args
.
length 
>
 
0
)
 limitItem 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
if
 
(
args
.
length 
>
 
1
)
 limitPass 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
do
 
{

            
String
[]
 a 
=
 
new
 
String
[
limitItem
];

            
StdOut
.
printf
(
“Creating dataset (%d items)…\n”
,
 limitItem
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  limitItem ;  i ++ )                 a [ i ]   =   Integer . toString ( i ,   16 );              StdOut . printf ( "Shuffling...\n" );              StdRandom . shuffle ( a );              StdOut . printf ( "Adding (%d items)...\n" ,  limitItem );              for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )                 set . add ( a [ i ]);              int  countItems  =   0 ;              StdOut . printf ( "Iterating...\n" );              for   ( String  key  :  set )  countItems ++ ;              StdOut . printf ( "%d items iterated\n" ,  countItems );              if   ( countItems  !=  limitItem )   ok  =   false ;              if   ( countItems  !=  set . size ())  ok  =   false ;              StdOut . printf ( "Shuffling...\n" );              StdRandom . shuffle ( a );              int  limitDelete  =  limitItem  /   2 ;              StdOut . printf ( "Deleting (%d items)...\n" ,  limitDelete );              for   ( int  i  =   0 ;  i  <  limitDelete ;  i ++ )                 set . delete ( a [ i ]);             countItems  =   0 ;              StdOut . printf ( "Iterating...\n" );              for   ( String  key  :  set )  countItems ++ ;              StdOut . printf ( "%d items iterated\n" ,  countItems );              if   ( countItems  !=  limitItem  -  limitDelete )  ok  =   false ;              if   ( countItems  !=  set . size ())               ok  =   false ;              int  countDelete  =   0 ;              int  countRemain  =   0 ;              StdOut . printf ( "Checking...\n" );              for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )   {                  if   ( i  <  limitDelete )   {                      if   ( ! set . contains ( a [ i ]))  countDelete ++ ;                  }                  else   {                      if   ( set . contains ( a [ i ]))  countRemain ++ ;                  }              }              StdOut . printf ( "%d items found and %d (deleted) items missing\n" ,                 countRemain ,  countDelete );              if   ( countRemain  +  countDelete  !=  limitItem )   ok  =   false ;              if   ( countRemain                !=  set . size ())  ok  =   false ;              if   ( set . isEmpty ())                            ok  =   false ;              StdOut . printf ( "Deleting the rest (%d items)...\n" ,                 limitItem  -  countDelete );              for   ( int  i  =  countDelete ;  i  <  limitItem ;  i ++ )                 set . delete ( a [ i ]);              if   ( ! set . isEmpty ())  ok  =   false ;             countPass ++ ;              if   ( ok )   StdOut . printf ( "PASS %d TESTS SUCCEEDED\n" ,  countPass );              else      StdOut . printf ( "PASS %d TESTS FAILED\n" ,     countPass );          }   while   ( ok  &&  countPass  <  limitPass );          if   ( ! ok )   throw   new  java . lang . RuntimeException ( "TESTS FAILED" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/PatriciaST.java edu/princeton/cs/algs4/PatriciaST.java /******************************************************************************  *  Compilation:  javac PatriciaST.java  *  Execution:    java PatriciaST  *  Dependencies: StdOut.java StdRandom.java Queue.java  *  Data files:   n/a  *  *  A symbol table implementation based on PATRICIA.  *  *  % java PatriciaST 1000000 1  *  Creating dataset (1000000 items)...  *  Shuffling...  *  Adding (1000000 items)...  *  Iterating...  *  1000000 items iterated  *  Shuffling...  *  Deleting (500000 items)...  *  Iterating...  *  500000 items iterated  *  Checking...  *  500000 items found and 500000 (deleted) items missing  *  Deleting the rest (500000 items)...  *  PASS 1 TESTS SUCCEEDED  *  %  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  PatriciaST} class provides an implementation of an unordered  *  symbol table of key-value pairs, with the restriction that the key is of  *  class { @link  java.lang.String}. It supports the usual put,

 *  getcontainsdeletesize, and

 *  is-empty methods. It also provides a keys method for

 *  iterating over all of the keys. A symbol table implements the

 *  associative array abstraction: when associating a value with a key

 *  that is already in the symbol table, the convention is to replace the old

 *  value with the new value. Unlike {
@link
 java.util.Map}, this class uses the

 *  convention that values cannot be {
@code
 null}—setting the value

 *  associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This unordered symbol table class implements PATRICIA (Practical Algorithm

 *  to Retrieve Information Coded In Alphanumeric). In spite of the acronym,

 *  string keys are not limited to alphanumeric content. A key may possess any

 *  string value, except for the string of zero length (the empty string).

 *  

 *  Unlike other generic symbol table implementations that can accept a

 *  parameterized key type, this symbol table class can only accommodate keys

 *  of class {
@link
 java.lang.String}. This unfortunate restriction stems from a

 *  limitation in Java. Although Java provides excellent support for generic

 *  programming, the current infrastructure somewhat limits generic collection

 *  implementations to those that employ comparison-based or hash-based methods.

 *  PATRICIA does not employ comparisons or hashing; instead, it relies on

 *  bit-test operations. Because Java does not furnish any generic abstractions

 *  (or implementations) for bit-testing the contents of an object, providing

 *  support for generic keys using PATRICIA does not seem practical.

 *  

 *  PATRICIA is a variation of a trie, and it is often classified as a

 *  space-optimized trie. In a classical trie, each level represents a

 *  subsequent digit in a key. In PATRICIA, nodes only exist to identify the

 *  digits (bits) that distinguish the individual keys within the trie. Because

 *  PATRICIA uses a radix of two, each node has only two children, like a binary

 *  tree. Also like a binary tree, the number of nodes, within the trie, equals

 *  the number of keys. Consequently, some classify PATRICIA as a tree.

 *  

 *  The analysis of PATRICIA is complicated. The theoretical wost-case

 *  performance for a getput, or delete operation

 *  is O(N), when N is less than

 *  W (where W is the length in bits of the

 *  longest key), and O(W), when N is greater

 *  than W. However, the worst case is unlikely to occur with

 *  typical use. The average (and usual) performance of PATRICIA is

 *  approximately ~lg N for each getput, or

 *  delete operation. Although this appears to put PATRICIA on the same

 *  footing as binary trees, this time complexity represents the number of

 *  single-bit test operations (under PATRICIA), and not full-key comparisons

 *  (as required by binary trees). After the single-bit tests conclude, PATRICIA

 *  requires just one full-key comparison to confirm the existence (or absence)

 *  of the key (per getput, or delete operation).

 *  

 *  In practice, decent implementations of PATRICIA can often outperform

 *  balanced binary trees, and even hash tables. Although this particular

 *  implementation performs well, the source code was written with an emphasis

 *  on clarity, and not performance. PATRICIA performs admirably when its

 *  bit-testing loops are well tuned. Consider using the source code as a guide,

 *  should you need to produce an optimized implementation, for anther key type,

 *  or in another programming language.

 *  

 *  Other resources for PATRICIA:

 *  Sedgewick, R. (1990) Algorithms in C, Addison-Wesley

 *  Knuth, D. (1973) The Art of Computer Programming, Addison-Wesley

 *

 *  
@author
 John Hentosh (based on an implementation by Robert Sedgewick)

 */

public
 
class
 
PatriciaST
< Value >
 
{

    
private
 
Node
 head
;

    
private
 
int
 count
;

    
/* An inner Node class specifies the objects that hold each key-value pair.

     * The b value indicates the relevant bit position.

     */

    
private
 
class
 
Node
 
{

        
private
 
Node
 left
,
 right
;

        
private
 
String
 key
;

        
private
 
Value
 val
;

        
private
 
int
 b
;

        
public
 
Node
(
String
 key
,
 
Value
 val
,
 
int
 b
)
 
{

            
this
.
key 
=
 key
;

            
this
.
val 
=
 val
;

            
this
.

=
 b
;

        
}

    
};

    
/**

     * Initializes an empty PATRICIA-based symbol table.

     */

    
/* The constructor creates a head (sentinel) node that contains a

     * zero-length string.

     */

    
public
 
PatriciaST
()
 
{

        head 
=
 
new
 
Node
(
“”
,
 
null
,
 
0
);

        head
.
left 
=
 head
;

        head
.
right 
=
 head
;

        count 
=
 
0
;

    
}

    
/**

     * Places a key-value pair into the symbol table. If the table already

     * contains the specified key, then its associated value becomes updated.

     * If the value provided is {
@code
 null}, then the key becomes removed

     * from the symbol table.

     * 
@param
 key the key

     * 
@param
 val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if {
@code
 key} is the empty string.

     */

    
public
 
void
 put
(
String
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called put(null)”
);

        
if
 
(
key
.
length
()
 
==
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“invalid key”
);

        
if
 
(
val 
==
 
null
)
 delete
(
key
);

        
Node
 p
;

        
Node
 x 
=
 head
;

        
do
 
{

            p 
=
 x
;

            
if
 
(
safeBitTest
(
key
,
 x
.
b
))
 x 
=
 x
.
right
;

            
else
                       x 
=
 x
.
left
;

        
}
 
while
 
(
p
.

<  x . b );          if   ( ! x . key . equals ( key ))   {              int  b  =  firstDifferingBit ( x . key ,  key );             x  =  head ;              do   {                 p  =  x ;                  if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;                  else                        x  =  x . left ;              }   while   ( p . b  <  x . b  &&  x . b  <  b );              Node  t  =   new   Node ( key ,  val ,  b );              if   ( safeBitTest ( key ,  b ))   {                 t . left   =  x ;                 t . right  =  t ;              }              else   {                 t . left   =  t ;                 t . right  =  x ;              }              if   ( safeBitTest ( key ,  p . b ))  p . right  =  t ;              else                        p . left   =  t ;             count ++ ;          }          else  x . val  =  val ;      }      /**      * Retrieves the value associated with the given key.      *  @param  key the key      *  @return  the value associated with the given key if the key is in the      * symbol table and { @code  null} if the key is not in the symbol table      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      *  @throws  IllegalArgumentException if { @code  key} is the empty string.      */      public   Value  get ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called get(null)" );          if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );          Node  p ;          Node  x  =  head ;          do   {             p  =  x ;              if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;              else                        x  =  x . left ;          }   while   ( p . b  <  x . b );          if   ( x . key . equals ( key ))   return  x . val ;          else                     return   null ;      }      /**      * Removes a key and its associated value from the symbol table, if it      * exists.      *  @param  key the key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      *  @throws  IllegalArgumentException if { @code  key} is the empty string.      */      public   void  delete ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called delete(null)" );          if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );          Node  g ;               // previous previous (grandparent)          Node  p  =  head ;        // previous (parent)          Node  x  =  head ;        // node to delete          do   {             g  =  p ;             p  =  x ;              if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;              else                        x  =  x . left ;          }   while   ( p . b  <  x . b );          if   ( x . key . equals ( key ))   {              Node  z ;              Node  y  =  head ;              do   {              // find the true parent (z) of x                 z  =  y ;                  if   ( safeBitTest ( key ,  y . b ))  y  =  y . right ;                  else                        y  =  y . left ;              }   while   ( y  !=  x );              if   ( x  ==  p )   {     // case 1: remove (leaf node) x                  Node  c ;       // child of x                  if   ( safeBitTest ( key ,  x . b ))  c  =  x . left ;                  else                        c  =  x . right ;                  if   ( safeBitTest ( key ,  z . b ))  z . right  =  c ;                  else                        z . left   =  c ;              }              else   {            // case 2: p replaces (internal node) x                  Node  c ;       // child of p                  if   ( safeBitTest ( key ,  p . b ))  c  =  p . left ;                  else                        c  =  p . right ;                  if   ( safeBitTest ( key ,  g . b ))  g . right  =  c ;                  else                        g . left   =  c ;                  if   ( safeBitTest ( key ,  z . b ))  z . right  =  p ;                  else                        z . left   =  p ;                 p . left  =  x . left ;                 p . right  =  x . right ;                 p . b  =  x . b ;              }             count -- ;          }      }      /**      * Returns { @code  true} if the key-value pair, specified by the given      * key, exists within the symbol table.      *  @param  key the key      *  @return  { @code  true} if this symbol table contains the given      * { @code  key} and { @code  false} otherwise      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      *  @throws  IllegalArgumentException if { @code  key} is the empty string.      */      public   boolean  contains ( String  key )   {          return  get ( key )   !=   null ;      }      /**      * Returns { @code  true} if the symbol table is empty.      *  @return  { @code  true} if this symbol table is empty and      * { @code  false} otherwise      */      boolean  isEmpty ()   {          return  count  ==   0 ;      }      /**      * Returns the number of key-value pairs within the symbol table.      *  @return  the number of key-value pairs within this symbol table      */      int  size ()   {          return  count ;      }      /**      * Returns all keys in the symbol table as an { @code  Iterable}.      * To iterate over all of the keys in the symbol table named      * { @code  st}, use the foreach notation:      * { @code  for (Key key : st.keys())}.      *  @return  all keys in the symbol table as an { @code  Iterable}      */      public   Iterable < String >
 keys
()
 
{

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        
if
 
(
head
.
left  
!=
 head
)
 keys
(
head
.
left
,
  
0
,
 queue
);

        
if
 
(
head
.
right 
!=
 head
)
 keys
(
head
.
right
,
 
0
,
 queue
);

        
return
 queue
;

    
}

    
private
 
void
 keys
(
Node
 x
,
 
int
 b
,
 
Queue
< String >
 queue
)
 
{

        
if
 
(
x
.

>
 b
)
 
{

            keys
(
x
.
left
,
 x
.
b
,
 queue
);

            queue
.
enqueue
(
x
.
key
);

            keys
(
x
.
right
,
 x
.
b
,
 queue
);

        
}

    
}

    
/* The safeBitTest function logically appends a terminating sequence (when

     * required) to extend (logically) the string beyond its length.

     *

     * The inner loops of the get and put methods flow much better when they

     * are not concerned with the lengths of strings, so a trick is employed to

     * allow the get and put methods to view every string as an “infinite”

     * sequence of bits. Logically, every string gets a ‘\uffff’ character,

     * followed by an “infinite” sequence of ‘\u0000’ characters, appended to

     * the end.

     *

     * Note that the ‘\uffff’ character serves to mark the end of the string,

     * and it is necessary. Simply padding with ‘\u0000’ is insufficient to

     * make all unique Unicode strings “look” unique to the get and put methods

     * (because these methods do not regard string lengths).

     */

    
private
 
static
 
boolean
 safeBitTest
(
String
 key
,
 
int
 b
)
 
{

        
if
 
(

<  key . length ()   *   16 )        return  bitTest ( key ,  b )   !=   0 ;          if   ( b  >
 key
.
length
()
 
*
 
16
 
+
 
15
)
 
return
 
false
;
   
// padding

        
/* 16 bits of 0xffff */
         
return
 
true
;
    
// end marker

    
}

    
private
 
static
 
int
 bitTest
(
String
 key
,
 
int
 b
)
 
{

        
return
 
(
key
.
charAt
(

>>>
 
4
)
 
>>>
 
(

&
 
0xf
))
 
&
 
1
;

    
}

    
/* Like the safeBitTest function, the safeCharAt function makes every

     * string look like an “infinite” sequence of characters. Logically, every

     * string gets a ‘\uffff’ character, followed by an “infinite” sequence of

     * ‘\u0000’ characters, appended to the end.

     */

    
private
 
static
 
int
 safeCharAt
(
String
 key
,
 
int
 i
)
 
{

        
if
 
(

<  key . length ())   return  key . charAt ( i );          if   ( i  >
 key
.
length
())
 
return
 
0x0000
;
            
// padding

        
else
                  
return
 
0xffff
;
            
// end marker

    
}

    
/* For efficiency’s sake, the firstDifferingBit function compares entire

     * characters first, and then considers the individual bits (once it finds

     * two characters that do not match). Also, the least significant bits of

     * an individual character are examined first. There are many Unicode

     * alphabets where most (if not all) of the “action” occurs in the least

     * significant bits.

     *

     * Notice that the very first character comparison excludes the

     * least-significant bit. The firstDifferingBit function must never return

     * zero; otherwise, a node would become created as a child to the head

     * (sentinel) node that matches the bit-index value (zero) stored in the

     * head node. This would violate the invariant that bit-index values

     * increase as you descend into the trie.

     */

    
private
 
static
 
int
 firstDifferingBit
(
String
 k1
,
 
String
 k2
)
 
{

        
int
 i 
=
 
0
;

        
int
 c1 
=
 safeCharAt
(
k1
,
 
0
)
 
&
 
~
1
;

        
int
 c2 
=
 safeCharAt
(
k2
,
 
0
)
 
&
 
~
1
;

        
if
 
(
c1 
==
 c2
)
 
{

            i 
=
 
1
;

            
while
 
(
safeCharAt
(
k1
,
 i
)
 
==
 safeCharAt
(
k2
,
 i
))
 i
++
;

            c1 
=
 safeCharAt
(
k1
,
 i
);

            c2 
=
 safeCharAt
(
k2
,
 i
);

        
}

        
int
 b 
=
 
0
;

        
while
 
(((
c1 
>>>
 b
)
 
&
 
1
)
 
==
 
((
c2 
>>>
 b
)
 
&
 
1
))
 b
++
;

        
return
 i 
*
 
16
 
+
 b
;

    
}

    
/**

     * Unit tests the {
@code
 PatriciaST} data type.

     * This test fixture runs a series of tests on a randomly generated dataset.

     * You may specify up to two integer parameters on the command line. The

     * first parameter indicates the size of the dataset. The second parameter

     * controls the number of passes (a new random dataset becomes generated at

     * the start of each pass).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
PatriciaST
< Integer >
 st 
=
 
new
 
PatriciaST
< Integer >
();

        
int
 limitItem 
=
 
1000000
;

        
int
 limitPass 
=
 
1
;

        
int
 countPass 
=
 
0
;

        
boolean
 ok 
=
 
true
;

        
if
 
(
args
.
length 
>
 
0
)
 limitItem 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
if
 
(
args
.
length 
>
 
1
)
 limitPass 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
do
 
{

            
String
[]
 a 
=
 
new
 
String
[
limitItem
];

            
int
[]
    v 
=
 
new
 
int
[
limitItem
];

            
StdOut
.
printf
(
“Creating dataset (%d items)…\n”
,
 limitItem
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  limitItem ;  i ++ )   {                 a [ i ]   =   Integer . toString ( i ,   16 );                 v [ i ]   =  i ;              }              StdOut . printf ( "Shuffling...\n" );              StdRandom . shuffle ( v );              StdOut . printf ( "Adding (%d items)...\n" ,  limitItem );              for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )                 st . put ( a [ v [ i ]],  v [ i ]);              int  countKeys  =   0 ;              StdOut . printf ( "Iterating...\n" );              for   ( String  key  :  st . keys ())  countKeys ++ ;              StdOut . printf ( "%d items iterated\n" ,  countKeys );              if   ( countKeys  !=  limitItem )  ok  =   false ;              if   ( countKeys  !=  st . size ())  ok  =   false ;              StdOut . printf ( "Shuffling...\n" );              StdRandom . shuffle ( v );              int  limitDelete  =  limitItem  /   2 ;              StdOut . printf ( "Deleting (%d items)...\n" ,  limitDelete );              for   ( int  i  =   0 ;  i  <  limitDelete ;  i ++ )                 st . delete ( a [ v [ i ]]);             countKeys  =   0 ;              StdOut . printf ( "Iterating...\n" );              for   ( String  key  :  st . keys ())  countKeys ++ ;              StdOut . printf ( "%d items iterated\n" ,  countKeys );              if   ( countKeys  !=  limitItem  -  limitDelete )  ok  =   false ;              if   ( countKeys  !=  st . size ())                ok  =   false ;              int  countDelete  =   0 ;              int  countRemain  =   0 ;              StdOut . printf ( "Checking...\n" );              for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )   {                  if   ( i  <  limitDelete )   {                      if   ( ! st . contains ( a [ v [ i ]]))  countDelete ++ ;                  }                  else   {                      int  val  =  st . get ( a [ v [ i ]]);                      if   ( val  ==  v [ i ])  countRemain ++ ;                  }              }              StdOut . printf ( "%d items found and %d (deleted) items missing\n" ,                 countRemain ,  countDelete );              if   ( countRemain  +  countDelete  !=  limitItem )  ok  =   false ;              if   ( countRemain                !=  st . size ())  ok  =   false ;              if   ( st . isEmpty ())                            ok  =   false ;              StdOut . printf ( "Deleting the rest (%d items)...\n" ,                 limitItem  -  countDelete );              for   ( int  i  =  countDelete ;  i  <  limitItem ;  i ++ )                 st . delete ( a [ v [ i ]]);              if   ( ! st . isEmpty ())  ok  =   false ;             countPass ++ ;              if   ( ok )   StdOut . printf ( "PASS %d TESTS SUCCEEDED\n" ,  countPass );              else      StdOut . printf ( "PASS %d TESTS FAILED\n" ,     countPass );          }   while   ( ok  &&  countPass  <  limitPass );          if   ( ! ok )   throw   new  java . lang . RuntimeException ( "TESTS FAILED" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/PictureDump.java edu/princeton/cs/algs4/PictureDump.java /******************************************************************************  *  Compilation:  javac PictureDump.java  *  Execution:    java PictureDump width height < file  *  Dependencies: BinaryStdIn.java Picture.java  *  Data file:    http://introcs.cs.princeton.edu/stdlib/abra.txt  *    *  Reads in a binary file and writes out the bits as w-by-h picture,  *  with the 1 bits in black and the 0 bits in white.  *  *  % more abra.txt   *  ABRACADABRA!  *  *  % java PictureDump 16 6 < abra.txt  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . Color ; /**  *  The { @code  PictureDump} class provides a client for displaying the contents  *  of a binary file as a black-and-white picture.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  See also {
@link
 BinaryDump} and {
@link
 HexDump}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
PictureDump
 
{

    
// Do not instantiate.

    
private
 
PictureDump
()
 
{
 
}

    
/**

     * Reads in a sequence of bytes from standard input and draws

     * them to standard drawing output as a width-by-height picture,

     * using black for 1 and white for 0 (and red for any leftover

     * pixels).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 width 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 height 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
Picture
 picture 
=
 
new
 
Picture
(
width
,
 height
);

        
for
 
(
int
 row 
=
 
0
;
 row 
<  height ;  row ++ )   {              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  if   ( ! BinaryStdIn . isEmpty ())   {                      boolean  bit  =   BinaryStdIn . readBoolean ();                      if   ( bit )  picture . set ( col ,  row ,   Color . BLACK );                      else      picture . set ( col ,  row ,   Color . WHITE );                  }                  else   {                     picture . set ( col ,  row ,   Color . RED );                  }              }          }         picture . show ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Picture.java edu/princeton/cs/algs4/Picture.java /******************************************************************************  *  Compilation:  javac Picture.java  *  Execution:    java Picture imagename  *  Dependencies: none  *  *  Data type for manipulating individual pixels of an image. The original  *  image can be read from a file in JPG, GIF, or PNG format, or the  *  user can create a blank image of a given dimension. Includes methods for  *  displaying the image in a window on the screen or saving to a file.  *  *  % java Picture mandrill  *  *  Remarks  *  -------  *   - pixel (x, y) is column x and row y, where (0, 0) is upper left  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . Color ; import  java . awt . FileDialog ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . KeyEvent ; import  java . awt . image . BufferedImage ; import  java . io . File ; import  java . io . IOException ; import  java . net . URL ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . JPanel ; import  javax . swing . KeyStroke ; /**  *  This class provides methods for manipulating individual pixels of  *  an image using the RGB color format. The alpha component (for transparency)  *  is not currently supported.  *  The original image can be read from a { @code  PNG}, { @code  GIF},  *  or { @code  JPEG} file or the user can create a blank image of a given dimension.  *  This class includes methods for displaying the image in a window on  *  the screen or saving it to a file.  *  

 *  Pixel (colrow) is column col and row row.

 *  By default, the origin (0, 0) is the pixel in the top-left corner,

 *  which is a common convention in image processing.

 *  The method {
@link
 #setOriginLowerLeft()} change the origin to the lower left.

 *  

 *  The {
@code
 get()} and {
@code
 set()} methods use {
@link
 Color} objects to get

 *  or set the color of the specified pixel.

 *  The {
@code
 getRGB()} and {
@code
 setRGB()} methods use a 32-bit {
@code
 int}

 *  to encode the color, thereby avoiding the need to create temporary

 *  {
@code
 Color} objects. The red (R), green (G), and blue (B) components 

 *  are encoded using the least significant 24 bits.

 *  Given a 32-bit {
@code
 int} encoding the color, the following code extracts

 *  the RGB components:

 * 


 *  int r = (rgb >> 16) & 0xFF;

 *  int g = (rgb >>  8) & 0xFF;

 *  int b = (rgb >>  0) & 0xFF;

 *  

 

 *  Given the RGB components (8-bits each) of a color,

 *  the following statement packs it into a 32-bit {
@code
 int}:

 * 


 *  int rgb = (r << 16) + (g << 8) + (b << 0);

 * 

 

 *  

 *  A W-by-H picture uses ~ 4 W H bytes of memory,

 *  since the color of each pixel is encoded as a 32-bit int.

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *  See {
@link
 GrayscalePicture} for a version that supports grayscale images.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
Picture
 
implements
 
ActionListener
 
{

    
private
 
BufferedImage
 image
;
               
// the rasterized image

    
private
 
JFrame
 frame
;
                      
// on-screen view

    
private
 
String
 filename
;
                   
// name of file

    
private
 
boolean
 isOriginUpperLeft 
=
 
true
;
  
// location of origin

    
private
 
final
 
int
 width
,
 height
;
           
// width and height

   
/**

     * Creates a {
@code
 width}-by-{
@code
 height} picture, with {
@code
 width} columns

     * and {
@code
 height} rows, where each pixel is black.

     *

     * 
@param
 width the width of the picture

     * 
@param
 height the height of the picture

     * 
@throws
 IllegalArgumentException if {
@code
 width} is negative or zero

     * 
@throws
 IllegalArgumentException if {
@code
 height} is negative or zero

     */

    
public
 
Picture
(
int
 width
,
 
int
 height
)
 
{

        
if
 
(
width  
<=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );          if   ( height  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );          this . width   =  width ;          this . height  =  height ;         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );          // set to TYPE_INT_ARGB here and in next constructor to support transparency      }     /**      * Creates a new picture that is a deep copy of the argument picture.      *      *  @param   picture the picture to copy      *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}      */      public   Picture ( Picture  picture )   {          if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );         width   =  picture . width ();         height  =  picture . height ();         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );         filename  =  picture . filename ;         isOriginUpperLeft  =  picture . isOriginUpperLeft ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                 image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));      }     /**      * Creates a picture by reading an image from a file or URL.      *      *  @param   name the name of the file ( , .gif, or  ) or URL.      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   Picture ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          this . filename  =  name ;          try   {              // try to read from file in working directory              File  file  =   new   File ( name );              if   ( file . isFile ())   {                 image  =   ImageIO . read ( file );              }              else   {                  // resource relative to .class file                 URL url  =  getClass (). getResource ( filename );                  // resource relative to classloader root                  if   ( url  ==   null )   {                     url  =  getClass (). getClassLoader (). getResource ( name );                  }                  // or URL from web                  if   ( url  ==   null )   {                     url  =   new  URL ( name );                  }                 image  =   ImageIO . read ( url );              }              if   ( image  ==   null )   {                  throw   new   IllegalArgumentException ( "could not read image: "   +  name );              }             width   =  image . getWidth ( null );             height  =  image . getHeight ( null );          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );          }      }     /**      * Creates a picture by reading the image from a PNG, GIF, or JPEG file.      *      *  @param  file the file      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   Picture ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          try   {             image  =   ImageIO . read ( file );          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open file: "   +  file ,  ioe );          }          if   ( image  ==   null )   {              throw   new   IllegalArgumentException ( "could not read file: "   +  file );          }         width   =  image . getWidth ( null );         height  =  image . getHeight ( null );         filename  =  file . getName ();      }     /**      * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},      * { @link  JFrame} or other GUI widget.      *      *  @return  the { @code  JLabel}      */      public   JLabel  getJLabel ()   {          if   ( image  ==   null )   return   null ;           // no image available          ImageIcon  icon  =   new   ImageIcon ( image );          return   new   JLabel ( icon );      }     /**      * Sets the origin to be the upper left pixel. This is the default.      */      public   void  setOriginUpperLeft ()   {         isOriginUpperLeft  =   true ;      }     /**      * Sets the origin to be the lower left pixel.      */      public   void  setOriginLowerLeft ()   {         isOriginUpperLeft  =   false ;      }     /**      * Displays the picture in a window on the screen.      */      public   void  show ()   {          // create the GUI for viewing the image if needed          if   ( frame  ==   null )   {             frame  =   new   JFrame ();              JMenuBar  menuBar  =   new   JMenuBar ();              JMenu  menu  =   new   JMenu ( "File" );             menuBar . add ( menu );              JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );             menuItem1 . addActionListener ( this );              // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)                        menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                       Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));             menu . add ( menuItem1 );             frame . setJMenuBar ( menuBar );             frame . setContentPane ( getJLabel ());              // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);             frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );              if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );              else                   frame . setTitle ( filename );             frame . setResizable ( false );             frame . pack ();             frame . setVisible ( true );          }          // draw         frame . repaint ();      }     /**      * Returns the height of the picture.      *      *  @return  the height of the picture (in pixels)      */      public   int  height ()   {          return  height ;      }     /**      * Returns the width of the picture.      *      *  @return  the width of the picture (in pixels)      */      public   int  width ()   {          return  width ;      }      private   void  validateRowIndex ( int  row )   {          if   ( row  <   0   ||  row  >=
 height
())

            
throw
 
new
 
IllegalArgumentException
(
“row index must be between 0 and ”
 
+
 
(
height
()
 

 
1
)
 
+
 
“: ”
 
+
 row
);

    
}

    
private
 
void
 validateColumnIndex
(
int
 col
)
 
{

        
if
 
(
col 
<   0   ||  col  >=
 width
())

            
throw
 
new
 
IllegalArgumentException
(
“column index must be between 0 and ”
 
+
 
(
width
()
 

 
1
)
 
+
 
“: ”
 
+
 col
);

    
}

   
/**

     * Returns the color of pixel ({
@code
 col}, {
@code
 row}) as a {
@link
 java.awt.Color}.

     *

     * 
@param
 col the column index

     * 
@param
 row the row index

     * 
@return
 the color of pixel ({
@code
 col}, {
@code
 row})

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= col < width} and { @code  0 <= row < height}      */      public   Color  get ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          int  rgb  =  getRGB ( col ,  row );          return   new   Color ( rgb );      }     /**      * Returns the color of pixel ({ @code  col}, { @code  row}) as an { @code  int}.      * Using this method can be more efficient than { @link  #get(int, int)} because      * it does not create a { @code  Color} object.      *      *  @param  col the column index      *  @param  row the row index      *  @return  the integer representation of the color of pixel ({ @code  col}, { @code  row})      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   int  getRGB ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row );          else                     return  image . getRGB ( col ,  height  -  row  -   1 );      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.      *      *  @param  col the column index      *  @param  row the row index      *  @param  color the color      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  set ( int  col ,   int  row ,   Color  color )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );          int  rgb  =  color . getRGB ();         setRGB ( col ,  row ,  rgb );      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.      *      *  @param  col the column index      *  @param  row the row index      *  @param  rgb the integer representation of the color      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   void  setRGB ( int  col ,   int  row ,   int  rgb )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );          else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );      }     /**      * Returns true if this picture is equal to the argument picture.      *      *  @param  other the other picture      *  @return  { @code  true} if this picture is the same dimension as { @code  other}      *         and if all pixels have the same color; { @code  false} otherwise      */      public   boolean  equals ( Object  other )   {          if   ( other  ==   this )   return   true ;          if   ( other  ==   null )   return   false ;          if   ( other . getClass ()   !=   this . getClass ())   return   false ;          Picture  that  =   ( Picture )  other ;          if   ( this . width ()    !=  that . width ())    return   false ;          if   ( this . height ()   !=  that . height ())   return   false ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                  if   ( this . getRGB ( col ,  row )   !=  that . getRGB ( col ,  row ))   return   false ;          return   true ;      }     /**      * Returns a string representation of this picture.      * The result is a width-by-height matrix of pixels,

     * where the color of a pixel is represented using 6 hex digits to encode

     * the red, green, and blue components.

     *

     * 
@return
 a string representation of this picture

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 sb 
=
 
new
 
StringBuilder
();

        sb
.
append
(
width 
+
“-by-”
 
+
 height 
+
 
” picture (RGB values given in hex)\n”
);

        
for
 
(
int
 row 
=
 
0
;
 row 
<  height ;  row ++ )   {              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  int  rgb  =   0 ;                  if   ( isOriginUpperLeft )  rgb  =  image . getRGB ( col ,  row );                  else                    rgb  =  image . getRGB ( col ,  height  -  row  -   1 );                 sb . append ( String . format ( "#%06X " ,  rgb  &   0xFFFFFF ));              }             sb . append ( "\n" );          }          return  sb . toString (). trim ();      }      /**      * This operation is not supported because pictures are mutable.      *      *  @return  does not return a value      *  @throws  UnsupportedOperationException if called      */      public   int  hashCode ()   {          throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );      }     /**      * Saves the picture to a file in either PNG or JPEG format.      * The filetype extension must be either   or  .      *      *  @param  name the name of the file      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   void  save ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         save ( new   File ( name ));         filename  =  name ;      }     /**      * Saves the picture to a file in a PNG or JPEG image format.      *      *  @param   file the file      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   void  save ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         filename  =  file . getName ();          if   ( frame  !=   null )  frame . setTitle ( filename );          String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );          if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {              try   {                  ImageIO . write ( image ,  suffix ,  file );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }          }          else   {              System . out . println ( "Error: filename must end in   or  " );          }      }     /**      * Opens a save dialog box when the user selects "Save As" from the menu.      */     @ Override      public   void  actionPerformed ( ActionEvent  e )   {          FileDialog  chooser  =   new   FileDialog ( frame ,                               "Use a   or   extension" ,   FileDialog . SAVE );         chooser . setVisible ( true );          if   ( chooser . getFile ()   !=   null )   {             save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());          }      }     /**      * Unit tests this { @code  Picture} data type.      * Reads a picture specified by the command-line argument,      * and shows it in a window on the screen.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          Picture  picture  =   new   Picture ( args [ 0 ]);          System . out . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());         picture . show ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Point2D.java edu/princeton/cs/algs4/Point2D.java /******************************************************************************  *  Compilation:  javac Point2D.java  *  Execution:    java Point2D x0 y0 n  *  Dependencies: StdDraw.java StdRandom.java  *  *  Immutable point data type for points in the plane.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; import  java . util . Comparator ; /**  *  The { @code  Point} class is an immutable data type to encapsulate a  *  two-dimensional point with real-value coordinates.  *  

 *  Note: in order to deal with the difference behavior of double and 

 *  Double with respect to -0.0 and +0.0, the Point2D constructor converts

 *  any coordinates that are -0.0 to +0.0.

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
Point2D
 
implements
 
Comparable
< Point2D >
 
{

    
/**

     * Compares two points by x-coordinate.

     */

    
public
 
static
 
final
 
Comparator
< Point2D >
 X_ORDER 
=
 
new
 
XOrder
();

    
/**

     * Compares two points by y-coordinate.

     */

    
public
 
static
 
final
 
Comparator
< Point2D >
 Y_ORDER 
=
 
new
 
YOrder
();

    
/**

     * Compares two points by polar radius.

     */

    
public
 
static
 
final
 
Comparator
< Point2D >
 R_ORDER 
=
 
new
 
ROrder
();

    
private
 
final
 
double
 x
;
    
// x coordinate

    
private
 
final
 
double
 y
;
    
// y coordinate

    
/**

     * Initializes a new point (x, y).

     * 
@param
 x the x-coordinate

     * 
@param
 y the y-coordinate

     * 
@throws
 IllegalArgumentException if either {
@code
 x} or {
@code
 y}

     *    is {
@code
 Double.NaN}, {
@code
 Double.POSITIVE_INFINITY} or

     *    {
@code
 Double.NEGATIVE_INFINITY}

     */

    
public
 
Point2D
(
double
 x
,
 
double
 y
)
 
{

        
if
 
(
Double
.
isInfinite
(
x
)
 
||
 
Double
.
isInfinite
(
y
))

            
throw
 
new
 
IllegalArgumentException
(
“Coordinates must be finite”
);

        
if
 
(
Double
.
isNaN
(
x
)
 
||
 
Double
.
isNaN
(
y
))

            
throw
 
new
 
IllegalArgumentException
(
“Coordinates cannot be NaN”
);

        
if
 
(

==
 
0.0
)
 
this
.

=
 
0.0
;
  
// convert -0.0 to +0.0

        
else
          
this
.

=
 x
;

        
if
 
(

==
 
0.0
)
 
this
.

=
 
0.0
;
  
// convert -0.0 to +0.0

        
else
          
this
.

=
 y
;

    
}

    
/**

     * Returns the x-coordinate.

     * 
@return
 the x-coordinate

     */

    
public
 
double
 x
()
 
{

        
return
 x
;

    
}

    
/**

     * Returns the y-coordinate.

     * 
@return
 the y-coordinate

     */

    
public
 
double
 y
()
 
{

        
return
 y
;

    
}

    
/**

     * Returns the polar radius of this point.

     * 
@return
 the polar radius of this point in polar coordiantes: sqrt(x*x + y*y)

     */

    
public
 
double
 r
()
 
{

        
return
 
Math
.
sqrt
(
x
*

+
 y
*
y
);

    
}

    
/**

     * Returns the angle of this point in polar coordinates.

     * 
@return
 the angle (in radians) of this point in polar coordiantes (between –π and π)

     */

    
public
 
double
 theta
()
 
{

        
return
 
Math
.
atan2
(
y
,
 x
);

    
}

    
/**

     * Returns the angle between this point and that point.

     * 
@return
 the angle in radians (between –π and π) between this point and that point (0 if equal)

     */

    
private
 
double
 angleTo
(
Point2D
 that
)
 
{

        
double
 dx 
=
 that
.


 
this
.
x
;

        
double
 dy 
=
 that
.


 
this
.
y
;

        
return
 
Math
.
atan2
(
dy
,
 dx
);

    
}

    
/**

     * Returns true if a→b→c is a counterclockwise turn.

     * 
@param
 a first point

     * 
@param
 b second point

     * 
@param
 c third point

     * 
@return
 { -1, 0, +1 } if a→b→c is a { clockwise, collinear; counterclocwise } turn.

     */

    
public
 
static
 
int
 ccw
(
Point2D
 a
,
 
Point2D
 b
,
 
Point2D
 c
)
 
{

        
double
 area2 
=
 
(
b
.
x

a
.
x
)
*
(
c
.
y

a
.
y
)
 

 
(
b
.
y

a
.
y
)
*
(
c
.
x

a
.
x
);

        
if
      
(
area2 
<   0 )   return   - 1 ;          else   if   ( area2  >
 
0
)
 
return
 
+
1
;

        
else
                
return
  
0
;

    
}

    
/**

     * Returns twice the signed area of the triangle a-b-c.

     * 
@param
 a first point

     * 
@param
 b second point

     * 
@param
 c third point

     * 
@return
 twice the signed area of the triangle a-b-c

     */

    
public
 
static
 
double
 area2
(
Point2D
 a
,
 
Point2D
 b
,
 
Point2D
 c
)
 
{

        
return
 
(
b
.
x

a
.
x
)
*
(
c
.
y

a
.
y
)
 

 
(
b
.
y

a
.
y
)
*
(
c
.
x

a
.
x
);

    
}

    
/**

     * Returns the Euclidean distance between this point and that point.

     * 
@param
 that the other point

     * 
@return
 the Euclidean distance between this point and that point

     */

    
public
 
double
 distanceTo
(
Point2D
 that
)
 
{

        
double
 dx 
=
 
this
.


 that
.
x
;

        
double
 dy 
=
 
this
.


 that
.
y
;

        
return
 
Math
.
sqrt
(
dx
*
dx 
+
 dy
*
dy
);

    
}

    
/**

     * Returns the square of the Euclidean distance between this point and that point.

     * 
@param
 that the other point

     * 
@return
 the square of the Euclidean distance between this point and that point

     */

    
public
 
double
 distanceSquaredTo
(
Point2D
 that
)
 
{

        
double
 dx 
=
 
this
.


 that
.
x
;

        
double
 dy 
=
 
this
.


 that
.
y
;

        
return
 dx
*
dx 
+
 dy
*
dy
;

    
}

    
/**

     * Compares two points by y-coordinate, breaking ties by x-coordinate.

     * Formally, the invoking point (x0, y0) is less than the argument point (x1, y1)

     * if and only if either {
@code
 y0 < y1} or if { @code  y0 == y1} and { @code  x0 < x1}.      *      *  @param   that the other point      *  @return  the value { @code  0} if this string is equal to the argument      *         string (precisely when { @code  equals()} returns { @code  true});      *         a negative integer if this point is less than the argument      *         point; and a positive integer if this point is greater than the      *         argument point      */      public   int  compareTo ( Point2D  that )   {          if   ( this . y  <  that . y )   return   - 1 ;          if   ( this . y  >
 that
.
y
)
 
return
 
+
1
;

        
if
 
(
this
.

<  that . x )   return   - 1 ;          if   ( this . x  >
 that
.
x
)
 
return
 
+
1
;

        
return
 
0
;

    
}

    
/**

     * Compares two points by polar angle (between 0 and 2π) with respect to this point.

     *

     * 
@return
 the comparator

     */

    
public
 
Comparator
< Point2D >
 polarOrder
()
 
{

        
return
 
new
 
PolarOrder
();

    
}

    
/**

     * Compares two points by atan2() angle (between –π and π) with respect to this point.

     *

     * 
@return
 the comparator

     */

    
public
 
Comparator
< Point2D >
 atan2Order
()
 
{

        
return
 
new
 
Atan2Order
();

    
}

    
/**

     * Compares two points by distance to this point.

     *

     * 
@return
 the comparator

     */

    
public
 
Comparator
< Point2D >
 distanceToOrder
()
 
{

        
return
 
new
 
DistanceToOrder
();

    
}

    
// compare points according to their x-coordinate

    
private
 
static
 
class
 
XOrder
 
implements
 
Comparator
< Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 p
,
 
Point2D
 q
)
 
{

            
if
 
(
p
.

<  q . x )   return   - 1 ;              if   ( p . x  >
 q
.
x
)
 
return
 
+
1
;

            
return
 
0
;

        
}

    
}

    
// compare points according to their y-coordinate

    
private
 
static
 
class
 
YOrder
 
implements
 
Comparator
< Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 p
,
 
Point2D
 q
)
 
{

            
if
 
(
p
.

<  q . y )   return   - 1 ;              if   ( p . y  >
 q
.
y
)
 
return
 
+
1
;

            
return
 
0
;

        
}

    
}

    
// compare points according to their polar radius

    
private
 
static
 
class
 
ROrder
 
implements
 
Comparator
< Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 p
,
 
Point2D
 q
)
 
{

            
double
 delta 
=
 
(
p
.
x
*
p
.

+
 p
.
y
*
p
.
y
)
 

 
(
q
.
x
*
q
.

+
 q
.
y
*
q
.
y
);

            
if
 
(
delta 
<   0 )   return   - 1 ;              if   ( delta  >
 
0
)
 
return
 
+
1
;

            
return
 
0
;

        
}

    
}

 

    
// compare other points relative to atan2 angle (bewteen -pi/2 and pi/2) they make with this Point

    
private
 
class
 
Atan2Order
 
implements
 
Comparator
< Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 q1
,
 
Point2D
 q2
)
 
{

            
double
 angle1 
=
 angleTo
(
q1
);

            
double
 angle2 
=
 angleTo
(
q2
);

            
if
      
(
angle1 
<  angle2 )   return   - 1 ;              else   if   ( angle1  >
 angle2
)
 
return
 
+
1
;

            
else
                      
return
  
0
;

        
}

    
}

    
// compare other points relative to polar angle (between 0 and 2pi) they make with this Point

    
private
 
class
 
PolarOrder
 
implements
 
Comparator
< Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 q1
,
 
Point2D
 q2
)
 
{

            
double
 dx1 
=
 q1
.


 x
;

            
double
 dy1 
=
 q1
.


 y
;

            
double
 dx2 
=
 q2
.


 x
;

            
double
 dy2 
=
 q2
.


 y
;

            
if
      
(
dy1 
>=
 
0
 
&&
 dy2 
<   0 )   return   - 1 ;      // q1 above; q2 below              else   if   ( dy2  >=
 
0
 
&&
 dy1 
<   0 )   return   + 1 ;      // q1 below; q2 above              else   if   ( dy1  ==   0   &&  dy2  ==   0 )   {              // 3-collinear and horizontal                  if        ( dx1  >=
 
0
 
&&
 dx2 
<   0 )   return   - 1 ;                  else   if   ( dx2  >=
 
0
 
&&
 dx1 
<   0 )   return   + 1 ;                  else                            return    0 ;              }              else   return   - ccw ( Point2D . this ,  q1 ,  q2 );       // both above or below              // Note: ccw() recomputes dx1, dy1, dx2, and dy2          }      }      // compare points according to their distance to this point      private   class   DistanceToOrder   implements   Comparator < Point2D >
 
{

        
public
 
int
 compare
(
Point2D
 p
,
 
Point2D
 q
)
 
{

            
double
 dist1 
=
 distanceSquaredTo
(
p
);

            
double
 dist2 
=
 distanceSquaredTo
(
q
);

            
if
      
(
dist1 
<  dist2 )   return   - 1 ;              else   if   ( dist1  >
 dist2
)
 
return
 
+
1
;

            
else
                    
return
  
0
;

        
}

    
}

    
/**       

     * Compares this point to the specified point.

     *       

     * 
@param
  other the other point

     * 
@return
 {
@code
 true} if this point equals {
@code
 other};

     *         {
@code
 false} otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
Point2D
 that 
=
 
(
Point2D
)
 other
;

        
return
 
this
.

==
 that
.

&&
 
this
.

==
 that
.
y
;

    
}

    
/**

     * Return a string representation of this point.

     * 
@return
 a string representation of this point in the format (x, y)

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
return
 
“(”
 
+
 x 
+
 
“, ”
 
+
 y 
+
 
“)”
;

    
}

    
/**

     * Returns an integer hash code for this point.

     * 
@return
 an integer hash code for this point

     */

    @
Override

    
public
 
int
 hashCode
()
 
{

        
int
 hashX 
=
 
((
Double
)
 x
).
hashCode
();

        
int
 hashY 
=
 
((
Double
)
 y
).
hashCode
();

        
return
 
31
*
hashX 
+
 hashY
;

    
}

    
/**

     * Plot this point using standard draw.

     */

    
public
 
void
 draw
()
 
{

        
StdDraw
.
point
(
x
,
 y
);

    
}

    
/**

     * Plot a line from this point to that point using standard draw.

     * 
@param
 that the other point

     */

    
public
 
void
 drawTo
(
Point2D
 that
)
 
{

        
StdDraw
.
line
(
this
.
x
,
 
this
.
y
,
 that
.
x
,
 that
.
y
);

    
}

    
/**

     * Unit tests the point data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 x0 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 y0 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
2
]);

        
StdDraw
.
setCanvasSize
(
800
,
 
800
);

        
StdDraw
.
setXscale
(
0
,
 
100
);

        
StdDraw
.
setYscale
(
0
,
 
100
);

        
StdDraw
.
setPenRadius
(
0.005
);

        
StdDraw
.
enableDoubleBuffering
();

        
Point2D
[]
 points 
=
 
new
 
Point2D
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  x  =   StdRandom . uniform ( 100 );              int  y  =   StdRandom . uniform ( 100 );             points [ i ]   =   new   Point2D ( x ,  y );             points [ i ]. draw ();          }          // draw p = (x0, x1) in red          Point2D  p  =   new   Point2D ( x0 ,  y0 );          StdDraw . setPenColor ( StdDraw . RED );          StdDraw . setPenRadius ( 0.02 );         p . draw ();          // draw line segments from p to each point, one at a time, in polar order          StdDraw . setPenRadius ();          StdDraw . setPenColor ( StdDraw . BLUE );          Arrays . sort ( points ,  p . polarOrder ());          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             p . drawTo ( points [ i ]);              StdDraw . show ();              StdDraw . pause ( 100 );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Polynomial.java edu/princeton/cs/algs4/Polynomial.java /******************************************************************************  *  Compilation:  javac Polynomial.java  *  Execution:    java Polynomial  *  *  Polynomials with integer coefficients.  *  *  % java Polynomial  *  zero(x)     = 0  *  p(x)        = 4x^3 + 3x^2 + 2x + 1  *  q(x)        = 3x^2 + 5  *  p(x) + q(x) = 4x^3 + 6x^2 + 2x + 6  *  p(x) * q(x) = 12x^5 + 9x^4 + 26x^3 + 18x^2 + 10x + 5  *  p(q(x))     = 108x^6 + 567x^4 + 996x^2 + 586  *  p(x) - p(x) = 0  *  0 - p(x)    = -4x^3 - 3x^2 - 2x - 1  *  p(3)        = 142  *  p'(x)       = 12x^2 + 6x + 2  *  p''(x)      = 24x + 6  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Polynomial} class represents a polynomial with integer  *  coefficients.  *  Polynomials are immutable: their values cannot be changed after they  *  are created.  *  It includes methods for addition, subtraction, multiplication, composition,  *  differentiation, and evaluation.  *  

 *  For additional documentation,

 *  see Section 9.9 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Polynomial
 
{

    
private
 
int
[]
 coef
;
   
// coefficients p(x) = sum { coef[i] * x^i }

    
private
 
int
 degree
;
   
// degree of polynomial (-1 for the zero polynomial)

    
/**

     * Initializes a new polynomial a x^b

     * 
@param
 a the leading coefficient

     * 
@param
 b the exponent

     * 
@throws
 IllegalArgumentException if {
@code
 b} is negative

     */

    
public
 
Polynomial
(
int
 a
,
 
int
 b
)
 
{

        
if
 
(

<   0 )   {              throw   new   IllegalArgumentException ( "exponent cannot be negative: "   +  b );          }         coef  =   new   int [ b + 1 ];         coef [ b ]   =  a ;         reduce ();      }      // pre-compute the degree of the polynomial, in case of leading zero coefficients      // (that is, the length of the array need not relate to the degree of the polynomial)      private   void  reduce ()   {         degree  =   - 1 ;          for   ( int  i  =  coef . length  -   1 ;  i  >=
 
0
;
 i

)
 
{

            
if
 
(
coef
[
i
]
 
!=
 
0
)
 
{

                degree 
=
 i
;

                
return
;

            
}

        
}

    
}

    
/**

     * Returns the degree of this polynomial.

     * 
@return
 the degree of this polynomial, -1 for the zero polynomial.

     */

    
public
 
int
 degree
()
 
{

        
return
 degree
;

    
}

    
/**

     * Returns the sum of this polynomial and the specified polynomial.

     *

     * 
@param
  that the other polynomial

     * 
@return
 the polynomial whose value is {
@code
 (this(x) + that(x))}

     */

    
public
 
Polynomial
 plus
(
Polynomial
 that
)
 
{

        
Polynomial
 poly 
=
 
new
 
Polynomial
(
0
,
 
Math
.
max
(
this
.
degree
,
 that
.
degree
));

        
for
 
(
int
 i 
=
 
0
;
 i 
<=   this . degree ;  i ++ )  poly . coef [ i ]   +=   this . coef [ i ];          for   ( int  i  =   0 ;  i  <=  that . degree ;  i ++ )  poly . coef [ i ]   +=  that . coef [ i ];         poly . reduce ();          return  poly ;      }      /**      * Returns the result of subtracting the specified polynomial      * from this polynomial.      *      *  @param   that the other polynomial      *  @return  the polynomial whose value is { @code  (this(x) - that(x))}      */      public   Polynomial  minus ( Polynomial  that )   {          Polynomial  poly  =   new   Polynomial ( 0 ,   Math . max ( this . degree ,  that . degree ));          for   ( int  i  =   0 ;  i  <=   this . degree ;  i ++ )  poly . coef [ i ]   +=   this . coef [ i ];          for   ( int  i  =   0 ;  i  <=  that . degree ;  i ++ )  poly . coef [ i ]   -=  that . coef [ i ];         poly . reduce ();          return  poly ;      }      /**      * Returns the product of this polynomial and the specified polynomial.      * Takes time proportional to the product of the degrees.      * (Faster algorithms are known, e.g., via FFT.)      *      *  @param   that the other polynomial      *  @return  the polynomial whose value is { @code  (this(x) * that(x))}      */      public   Polynomial  times ( Polynomial  that )   {          Polynomial  poly  =   new   Polynomial ( 0 ,   this . degree  +  that . degree );          for   ( int  i  =   0 ;  i  <=   this . degree ;  i ++ )              for   ( int  j  =   0 ;  j  <=  that . degree ;  j ++ )                 poly . coef [ i + j ]   +=   ( this . coef [ i ]   *  that . coef [ j ]);         poly . reduce ();          return  poly ;      }      /**      * Returns the composition of this polynomial and the specified      * polynomial.      * Takes time proportional to the product of the degrees.      * (Faster algorithms are known, e.g., via FFT.)      *      *  @param   that the other polynomial      *  @return  the polynomial whose value is { @code  (this(that(x)))}      */      public   Polynomial  compose ( Polynomial  that )   {          Polynomial  poly  =   new   Polynomial ( 0 ,   0 );          for   ( int  i  =   this . degree ;  i  >=
 
0
;
 i

)
 
{

            
Polynomial
 term 
=
 
new
 
Polynomial
(
this
.
coef
[
i
],
 
0
);

            poly 
=
 term
.
plus
(
that
.
times
(
poly
));

        
}

        
return
 poly
;

    
}

    
/**       

     * Compares this polynomial to the specified polynomial.

     *       

     * 
@param
  other the other polynoimal

     * 
@return
 {
@code
 true} if this polynomial equals {
@code
 other};

     *         {
@code
 false} otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
Polynomial
 that 
=
 
(
Polynomial
)
 other
;

        
if
 
(
this
.
degree 
!=
 that
.
degree
)
 
return
 
false
;

        
for
 
(
int
 i 
=
 
this
.
degree
;
 i 
>=
 
0
;
 i

)

            
if
 
(
this
.
coef
[
i
]
 
!=
 that
.
coef
[
i
])
 
return
 
false
;

        
return
 
true
;

    
}

    
/**

     * Returns the result of differentiating this polynomial.

     *

     * 
@return
 the polynomial whose value is {
@code
 this'(x)}

     */

    
public
 
Polynomial
 differentiate
()
 
{

        
if
 
(
degree 
==
 
0
)
 
return
 
new
 
Polynomial
(
0
,
 
0
);

        
Polynomial
 poly 
=
 
new
 
Polynomial
(
0
,
 degree 

 
1
);

        poly
.
degree 
=
 degree 

 
1
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  degree ;  i ++ )             poly . coef [ i ]   =   ( i  +   1 )   *  coef [ i  +   1 ];          return  poly ;      }      /**      * Returns the result of evaluating this polynomial at the point x.      *      *  @param   x the point at which to evaluate the polynomial      *  @return  the integer whose value is { @code  (this(x))}      */      public   int  evaluate ( int  x )   {          int  p  =   0 ;          for   ( int  i  =  degree ;  i  >=
 
0
;
 i

)

            p 
=
 coef
[
i
]
 
+
 
(

*
 p
);

        
return
 p
;

    
}

    
/**

     * Compares two polynomials by degree, breaking ties by coefficient of leading term.

     *

     * 
@param
  that the other point

     * 
@return
 the value {
@code
 0} if this polynomial is equal to the argument

     *         polynomial (precisely when {
@code
 equals()} returns {
@code
 true});

     *         a negative integer if this polynomialt is less than the argument

     *         polynomial; and a positive integer if this polynomial is greater than the

     *         argument point

     */

    
public
 
int
 compareTo
(
Polynomial
 that
)
 
{

        
if
 
(
this
.
degree 
<  that . degree )   return   - 1 ;          if   ( this . degree  >
 that
.
degree
)
 
return
 
+
1
;

        
for
 
(
int
 i 
=
 
this
.
degree
;
 i 
>=
 
0
;
 i

)
 
{

            
if
 
(
this
.
coef
[
i
]
 
<  that . coef [ i ])   return   - 1 ;              if   ( this . coef [ i ]   >
 that
.
coef
[
i
])
 
return
 
+
1
;

        
}

        
return
 
0
;

    
}

    
/**

     * Return a string representation of this polynomial.

     * 
@return
 a string representation of this polynomial in the format

     *         4x^5 – 3x^2 + 11x + 5

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
if
      
(
degree 
==
 

1
)
 
return
 
“0”
;

        
else
 
if
 
(
degree 
==
  
0
)
 
return
 
“”
 
+
 coef
[
0
];

        
else
 
if
 
(
degree 
==
  
1
)
 
return
 coef
[
1
]
 
+
 
“x + ”
 
+
 coef
[
0
];

        
String
 s 
=
 coef
[
degree
]
 
+
 
“x^”
 
+
 degree
;

        
for
 
(
int
 i 
=
 degree 

 
1
;
 i 
>=
 
0
;
 i

)
 
{

            
if
      
(
coef
[
i
]
 
==
 
0
)
 
continue
;

            
else
 
if
 
(
coef
[
i
]
  
>
 
0
)
 s 
=
 s 
+
 
” + ”
 
+
 
(
coef
[
i
]);

            
else
 
if
 
(
coef
[
i
]
  
<   0 )  s  =  s  +   " - "   +   ( - coef [ i ]);              if        ( i  ==   1 )  s  =  s  +   "x" ;              else   if   ( i  >
  
1
)
 s 
=
 s 
+
 
“x^”
 
+
 i
;

        
}

        
return
 s
;

    
}

    
/**

     * Unit tests the polynomial data type.

     *

     * 
@param
 args the command-line arguments (none)

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{
 

        
Polynomial
 zero 
=
 
new
 
Polynomial
(
0
,
 
0
);

        
Polynomial
 p1   
=
 
new
 
Polynomial
(
4
,
 
3
);

        
Polynomial
 p2   
=
 
new
 
Polynomial
(
3
,
 
2
);

        
Polynomial
 p3   
=
 
new
 
Polynomial
(
1
,
 
0
);

        
Polynomial
 p4   
=
 
new
 
Polynomial
(
2
,
 
1
);

        
Polynomial
 p    
=
 p1
.
plus
(
p2
).
plus
(
p3
).
plus
(
p4
);
   
// 4x^3 + 3x^2 + 1

        
Polynomial
 q1   
=
 
new
 
Polynomial
(
3
,
 
2
);

        
Polynomial
 q2   
=
 
new
 
Polynomial
(
5
,
 
0
);

        
Polynomial
 q    
=
 q1
.
plus
(
q2
);
                     
// 3x^2 + 5

        
Polynomial
 r    
=
 p
.
plus
(
q
);

        
Polynomial
 s    
=
 p
.
times
(
q
);

        
Polynomial
 t    
=
 p
.
compose
(
q
);

        
Polynomial
 u    
=
 p
.
minus
(
p
);

        
StdOut
.
println
(
“zero(x)     = ”
 
+
 zero
);

        
StdOut
.
println
(
“p(x)        = ”
 
+
 p
);

        
StdOut
.
println
(
“q(x)        = ”
 
+
 q
);

        
StdOut
.
println
(
“p(x) + q(x) = ”
 
+
 r
);

        
StdOut
.
println
(
“p(x) * q(x) = ”
 
+
 s
);

        
StdOut
.
println
(
“p(q(x))     = ”
 
+
 t
);

        
StdOut
.
println
(
“p(x) – p(x) = ”
 
+
 u
);

        
StdOut
.
println
(
“0 – p(x)    = ”
 
+
 zero
.
minus
(
p
));

        
StdOut
.
println
(
“p(3)        = ”
 
+
 p
.
evaluate
(
3
));

        
StdOut
.
println
(
“p'(x)       = ”
 
+
 p
.
differentiate
());

        
StdOut
.
println
(
“p”(x)      = ”
 
+
 p
.
differentiate
().
differentiate
());

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/PrimMST.java
edu/princeton/cs/algs4/PrimMST.java
/******************************************************************************

 *  Compilation:  javac PrimMST.java

 *  Execution:    java PrimMST filename.txt

 *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java

 *                IndexMinPQ.java UF.java In.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt

 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt

 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt

 *

 *  Compute a minimum spanning forest using Prim’s algorithm.

 *

 *  %  java PrimMST tinyEWG.txt 

 *  1-7 0.19000

 *  0-2 0.26000

 *  2-3 0.17000

 *  4-5 0.35000

 *  5-7 0.28000

 *  6-2 0.40000

 *  0-7 0.16000

 *  1.81000

 *

 *  % java PrimMST mediumEWG.txt

 *  1-72   0.06506

 *  2-86   0.05980

 *  3-67   0.09725

 *  4-55   0.06425

 *  5-102  0.03834

 *  6-129  0.05363

 *  7-157  0.00516

 *  …

 *  10.46351

 *

 *  % java PrimMST largeEWG.txt

 *  …

 *  647.66307

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 PrimMST} class represents a data type for computing a

 *  minimum spanning tree in an edge-weighted graph.

 *  The edge weights can be positive, zero, or negative and need not

 *  be distinct. If the graph is not connected, it computes a minimum

 *  spanning forest, which is the union of minimum spanning trees

 *  in each connected component. The {
@code
 weight()} method returns the 

 *  weight of a minimum spanning tree and the {
@code
 edges()} method

 *  returns its edges.

 *  

 *  This implementation uses Prim’s algorithm with an indexed

 *  binary heap.

 *  The constructor takes Θ(E log V) time in

 *  the worst case, where V is the number of

 *  vertices and E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the 

 *  edge-weighted graph).

 *  

 *  For additional documentation,

 *  see Section 4.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For alternate implementations, see {
@link
 LazyPrimMST}, {
@link
 KruskalMST},

 *  and {
@link
 BoruvkaMST}.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
PrimMST
 
{

    
private
 
static
 
final
 
double
 FLOATING_POINT_EPSILON 
=
 
1E-12
;

    
private
 
Edge
[]
 edgeTo
;
        
// edgeTo[v] = shortest edge from tree vertex to non-tree vertex

    
private
 
double
[]
 distTo
;
      
// distTo[v] = weight of shortest such edge

    
private
 
boolean
[]
 marked
;
     
// marked[v] = true if v on tree, false otherwise

    
private
 
IndexMinPQ
< Double >
 pq
;

    
/**

     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.

     * 
@param
 G the edge-weighted graph

     */

    
public
 
PrimMST
(
EdgeWeightedGraph
 G
)
 
{

        edgeTo 
=
 
new
 
Edge
[
G
.
V
()];

        distTo 
=
 
new
 
double
[
G
.
V
()];

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        pq 
=
 
new
 
IndexMinPQ
< Double >
(
G
.
V
());

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             distTo [ v ]   =   Double . POSITIVE_INFINITY ;          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )        // run from each vertex to find              if   ( ! marked [ v ])  prim ( G ,  v );        // minimum spanning forest          // check optimality conditions          assert  check ( G );      }      // run Prim's algorithm in graph G, starting from vertex s      private   void  prim ( EdgeWeightedGraph  G ,   int  s )   {         distTo [ s ]   =   0.0 ;         pq . insert ( s ,  distTo [ s ]);          while   ( ! pq . isEmpty ())   {              int  v  =  pq . delMin ();             scan ( G ,  v );          }      }      // scan vertex v      private   void  scan ( EdgeWeightedGraph  G ,   int  v )   {         marked [ v ]   =   true ;          for   ( Edge  e  :  G . adj ( v ))   {              int  w  =  e . other ( v );              if   ( marked [ w ])   continue ;           // v-w is obsolete edge              if   ( e . weight ()   <  distTo [ w ])   {                 distTo [ w ]   =  e . weight ();                 edgeTo [ w ]   =  e ;                  if   ( pq . contains ( w ))  pq . decreaseKey ( w ,  distTo [ w ]);                  else                 pq . insert ( w ,  distTo [ w ]);              }          }      }      /**      * Returns the edges in a minimum spanning tree (or forest).      *  @return  the edges in a minimum spanning tree (or forest) as      *    an iterable of edges      */      public   Iterable < Edge >
 edges
()
 
{

        
Queue
< Edge >
 mst 
=
 
new
 
Queue
< Edge >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  edgeTo . length ;  v ++ )   {              Edge  e  =  edgeTo [ v ];              if   ( e  !=   null )   {                 mst . enqueue ( e );              }          }          return  mst ;      }      /**      * Returns the sum of the edge weights in a minimum spanning tree (or forest).      *  @return  the sum of the edge weights in a minimum spanning tree (or forest)      */      public   double  weight ()   {          double  weight  =   0.0 ;          for   ( Edge  e  :  edges ())             weight  +=  e . weight ();          return  weight ;      }      // check optimality conditions (takes time proportional to E V lg* V)      private   boolean  check ( EdgeWeightedGraph  G )   {          // check weight          double  totalWeight  =   0.0 ;          for   ( Edge  e  :  edges ())   {             totalWeight  +=  e . weight ();          }          if   ( Math . abs ( totalWeight  -  weight ())   >
 FLOATING_POINT_EPSILON
)
 
{

            
System
.
err
.
printf
(
“Weight of edges does not equal weight(): %f vs. %f\n”
,
 totalWeight
,
 weight
());

            
return
 
false
;

        
}

        
// check that it is acyclic

        UF uf 
=
 
new
 UF
(
G
.
V
());

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
==
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a forest”
);

                
return
 
false
;

            
}

            uf
.
union
(
v
,
 w
);

        
}

        
// check that it is a spanning forest

        
for
 
(
Edge
 e 
:
 G
.
edges
())
 
{

            
int
 v 
=
 e
.
either
(),
 w 
=
 e
.
other
(
v
);

            
if
 
(
uf
.
find
(
v
)
 
!=
 uf
.
find
(
w
))
 
{

                
System
.
err
.
println
(
“Not a spanning forest”
);

                
return
 
false
;

            
}

        
}

        
// check that it is a minimal spanning forest (cut optimality conditions)

        
for
 
(
Edge
 e 
:
 edges
())
 
{

            
// all edges in MST except e

            uf 
=
 
new
 UF
(
G
.
V
());

            
for
 
(
Edge
 f 
:
 edges
())
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(

!=
 e
)
 uf
.
union
(
x
,
 y
);

            
}

            
// check that e is min weight edge in crossing cut

            
for
 
(
Edge
 f 
:
 G
.
edges
())
 
{

                
int
 x 
=
 f
.
either
(),
 y 
=
 f
.
other
(
x
);

                
if
 
(
uf
.
find
(
x
)
 
!=
 uf
.
find
(
y
))
 
{

                    
if
 
(
f
.
weight
()
 
<  e . weight ())   {                          System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );                          return   false ;                      }                  }              }          }          return   true ;      }      /**      * Unit tests the { @code  PrimMST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in  =   new   In ( args [ 0 ]);          EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );          PrimMST  mst  =   new   PrimMST ( G );          for   ( Edge  e  :  mst . edges ())   {              StdOut . println ( e );          }          StdOut . printf ( "%.5f\n" ,  mst . weight ());      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Queue.java edu/princeton/cs/algs4/Queue.java /******************************************************************************  *  Compilation:  javac Queue.java  *  Execution:    java Queue < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt    *  *  A generic queue, implemented using a linked list.  *  *  % java Queue < tobe.txt   *  to be or not to be (2 left on queue)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  Queue} class represents a first-in-first-out (FIFO)  *  queue of generic items.  *  It supports the usual enqueue and dequeue

 *  operations, along with methods for peeking at the first item,

 *  testing if the queue is empty, and iterating through

 *  the items in FIFO order.

 *  

 *  This implementation uses a singly linked list with a static nested class for

 *  linked-list nodes. See {
@link
 LinkedQueue} for the version from the

 *  textbook that uses a non-static nested class.

 *  See {
@link
 ResizingArrayQueue} for a version that uses a resizing array.

 *  The enqueuedequeuepeeksize, and is-empty

 *  operations all take constant time in the worst case.

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of an item in this queue

 */

public
 
class
 
Queue
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Node
< Item >
 first
;
    
// beginning of queue

    
private
 
Node
< Item >
 last
;
     
// end of queue

    
private
 
int
 n
;
               
// number of elements on queue

    
// helper linked list class

    
private
 
static
 
class
 
Node
< Item >
 
{

        
private
 
Item
 item
;

        
private
 
Node
< Item >
 next
;

    
}

    
/**

     * Initializes an empty queue.

     */

    
public
 
Queue
()
 
{

        first 
=
 
null
;

        last  
=
 
null
;

        n 
=
 
0
;

    
}

    
/**

     * Returns true if this queue is empty.

     *

     * 
@return
 {
@code
 true} if this queue is empty; {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in this queue.

     *

     * 
@return
 the number of items in this queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns the item least recently added to this queue.

     *

     * 
@return
 the item least recently added to this queue

     * 
@throws
 NoSuchElementException if this queue is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Queue underflow”
);

        
return
 first
.
item
;

    
}

    
/**

     * Adds the item to this queue.

     *

     * 
@param
  item the item to add

     */

    
public
 
void
 enqueue
(
Item
 item
)
 
{

        
Node
< Item >
 oldlast 
=
 last
;

        last 
=
 
new
 
Node
< Item >
();

        last
.
item 
=
 item
;

        last
.
next 
=
 
null
;

        
if
 
(
isEmpty
())
 first 
=
 last
;

        
else
           oldlast
.
next 
=
 last
;

        n
++
;

    
}

    
/**

     * Removes and returns the item on this queue that was least recently added.

     *

     * 
@return
 the item on this queue that was least recently added

     * 
@throws
 NoSuchElementException if this queue is empty

     */

    
public
 
Item
 dequeue
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Queue underflow”
);

        
Item
 item 
=
 first
.
item
;

        first 
=
 first
.
next
;

        n

;

        
if
 
(
isEmpty
())
 last 
=
 
null
;
   
// to avoid loitering

        
return
 item
;

    
}

    
/**

     * Returns a string representation of this queue.

     *

     * 
@return
 the sequence of items in FIFO order, separated by spaces

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        
for
 
(
Item
 item 
:
 
this
)
 
{

            s
.
append
(
item
);

            s
.
append
(
‘ ‘
);

        
}

        
return
 s
.
toString
();

    
}
 

    
/**

     * Returns an iterator that iterates over the items in this queue in FIFO order.

     *

     * 
@return
 an iterator that iterates over the items in this queue in FIFO order

     */

    
public
 
Iterator
< Item >
 iterator
()
  
{

        
return
 
new
 
ListIterator
(
first
);
  

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
< Item >
 current
;

        
public
 
ListIterator
(
Node
< Item >
 first
)
 
{

            current 
=
 first
;

        
}

        
public
 
boolean
 hasNext
()
  
{
 
return
 current 
!=
 
null
;
                     
}

        
public
 
void
 remove
()
      
{
 
throw
 
new
 
UnsupportedOperationException
();
  
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 Queue} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))

                queue
.
enqueue
(
item
);

            
else
 
if
 
(
!
queue
.
isEmpty
())

                
StdOut
.
print
(
queue
.
dequeue
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 queue
.
size
()
 
+
 
” left on queue)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Quick3string.java
edu/princeton/cs/algs4/Quick3string.java
/******************************************************************************

 *  Compilation:  javac Quick3string.java

 *  Execution:    java Quick3string < input.txt  *  Dependencies: StdIn.java StdOut.java   *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt  *                https://algs4.cs.princeton.edu/51radix/shells.txt  *  *  Reads string from standard input and 3-way string quicksort them.  *  *  % java Quick3string < shell.txt  *  are  *  by  *  sea  *  seashells  *  seashells  *  sells  *  sells  *  she  *  she  *  shells  *  shore  *  surely  *  the  *  the  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Quick3string} class provides static methods for sorting an  *  array of strings using 3-way radix quicksort.  *  

 *  For additional documentation,

 *  see Section 5.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Quick3string
 
{

    
private
 
static
 
final
 
int
 CUTOFF 
=
  
15
;
   
// cutoff to insertion sort

    
// do not instantiate

    
private
 
Quick3string
()
 
{
 
}
 

    
/**  

     * Rearranges the array of strings in ascending order.

     *

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
String
[]
 a
)
 
{

        
StdRandom
.
shuffle
(
a
);

        sort
(
a
,
 
0
,
 a
.
length

1
,
 
0
);

        
assert
 isSorted
(
a
);

    
}

    
// return the dth character of s, -1 if d = length of s

    
private
 
static
 
int
 charAt
(
String
 s
,
 
int
 d
)
 
{
 

        
assert
 d 
>=
 
0
 
&&
 d 
<=  s . length ();          if   ( d  ==  s . length ())   return   - 1 ;          return  s . charAt ( d );      }      // 3-way string quicksort a[lo..hi] starting at dth character      private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d )   {            // cutoff to insertion sort for small subarrays          if   ( hi  <=  lo  +  CUTOFF )   {             insertion ( a ,  lo ,  hi ,  d );              return ;          }          int  lt  =  lo ,  gt  =  hi ;          int  v  =  charAt ( a [ lo ],  d );          int  i  =  lo  +   1 ;          while   ( i  <=  gt )   {              int  t  =  charAt ( a [ i ],  d );              if        ( t  <  v )  exch ( a ,  lt ++ ,  i ++ );              else   if   ( t  >
 v
)
 exch
(
a
,
 i
,
 gt

);

            
else
              i
++
;

        
}

        
// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].          sort ( a ,  lo ,  lt - 1 ,  d );          if   ( v  >=
 
0
)
 sort
(
a
,
 lt
,
 gt
,
 d
+
1
);

        sort
(
a
,
 gt
+
1
,
 hi
,
 d
);

    
}

    
// sort from a[lo] to a[hi], starting at the dth character

    
private
 
static
 
void
 insertion
(
String
[]
 a
,
 
int
 lo
,
 
int
 hi
,
 
int
 d
)
 
{

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
],
 d
);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// exchange a[i] and a[j]

    
private
 
static
 
void
 exch
(
String
[]
 a
,
 
int
 i
,
 
int
 j
)
 
{

        
String
 temp 
=
 a
[
i
];

        a
[
i
]
 
=
 a
[
j
];

        a
[
j
]
 
=
 temp
;

    
}

    
// is v less than w, starting at character d

    
// DEPRECATED BECAUSE OF SLOW SUBSTRING EXTRACTION IN JAVA 7

    
// private static boolean less(String v, String w, int d) {

    
//    assert v.substring(0, d).equals(w.substring(0, d));

    
//    return v.substring(d).compareTo(w.substring(d)) < 0;       // }      // is v less than w, starting at character d      private   static   boolean  less ( String  v ,   String  w ,   int  d )   {          assert  v . substring ( 0 ,  d ). equals ( w . substring ( 0 ,  d ));          for   ( int  i  =  d ;  i  <   Math . min ( v . length (),  w . length ());  i ++ )   {              if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;              if   ( v . charAt ( i )   >
 w
.
charAt
(
i
))
 
return
 
false
;

        
}

        
return
 v
.
length
()
 
<  w . length ();      }      // is the array sorted      private   static   boolean  isSorted ( String []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( a [ i ]. compareTo ( a [ i - 1 ])   <   0 )   return   false ;          return   true ;      }      /**      * Reads in a sequence of fixed-length strings from standard input;      * 3-way radix quicksorts them;      * and prints them to standard output in ascending order.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read in the strings from standard input          String []  a  =   StdIn . readAllStrings ();          int  n  =  a . length ;          // sort the strings         sort ( a );          // print the results          for   ( int  i  =   0 ;  i  <  n ;  i ++ )              StdOut . println ( a [ i ]);      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Quick3way.java edu/princeton/cs/algs4/Quick3way.java /******************************************************************************  *  Compilation:  javac Quick3way.java  *  Execution:    java Quick3way < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt  *                https://algs4.cs.princeton.edu/23quicksort/words3.txt  *     *  Sorts a sequence of strings from standard input using 3-way quicksort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Quick3way < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java Quick3way < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Quick3way} class provides static methods for sorting an  *  array using quicksort with 3-way partitioning.  *  

 *  For additional documentation,

 *  see Section 2.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Quick3way
 
{

    
// This class should not be instantiated.

    
private
 
Quick3way
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
StdRandom
.
shuffle
(
a
);

        sort
(
a
,
 
0
,
 a
.
length 

 
1
);

        
assert
 isSorted
(
a
);

    
}

    
// quicksort the subarray a[lo .. hi] using 3-way partitioning

    
private
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{
 

        
if
 
(
hi 
<=  lo )   return ;          int  lt  =  lo ,  gt  =  hi ;          Comparable  v  =  a [ lo ];          int  i  =  lo  +   1 ;          while   ( i  <=  gt )   {              int  cmp  =  a [ i ]. compareTo ( v );              if        ( cmp  <   0 )  exch ( a ,  lt ++ ,  i ++ );              else   if   ( cmp  >
 
0
)
 exch
(
a
,
 i
,
 gt

);

            
else
              i
++
;

        
}

        
// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].          sort ( a ,  lo ,  lt - 1 );         sort ( a ,  gt + 1 ,  hi );          assert  isSorted ( a ,  lo ,  hi );      }     /***************************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length  -   1 );      }      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; 3-way      * quicksorts them; and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Quick3way . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/QuickBentleyMcIlroy.java edu/princeton/cs/algs4/QuickBentleyMcIlroy.java /******************************************************************************  *  Compilation:  javac QuickBentleyMcIlroy.java  *  Execution:    java QuickBentleyMcIlroy < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt  *                https://algs4.cs.princeton.edu/23quicksort/words3.txt  *    *  Uses the Bentley-McIlroy 3-way partitioning scheme,  *  chooses the partitioning element using Tukey's ninther,  *  and cuts off to insertion sort.  *  *  Reference: Engineering a Sort Function by Jon L. Bentley  *  and M. Douglas McIlroy. Softwae-Practice and Experience,  *  Vol. 23 (11), 1249-1265 (November 1993).  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  QuickBentleyMcIlroy} class provides static methods for sorting  *  an array using an optimized version of quicksort (using Bentley-McIlroy  *  3-way partitioning, Tukey's ninther, and cutoff to insertion sort).  *  

 *  For additional documentation,

 *  see Section 2.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
QuickBentleyMcIlroy
 
{

    
// cutoff to insertion sort, must be >= 1

    
private
 
static
 
final
 
int
 INSERTION_SORT_CUTOFF 
=
 
8
;

    
// cutoff to median-of-3 partitioning

    
private
 
static
 
final
 
int
 MEDIAN_OF_3_CUTOFF 
=
 
40
;

    
// This class should not be instantiated.

    
private
 
QuickBentleyMcIlroy
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        sort
(
a
,
 
0
,
 a
.
length 

 
1
);

    
}

    
private
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{
 

        
int
 n 
=
 hi 

 lo 
+
 
1
;

        
// cutoff to insertion sort

        
if
 
(

<=  INSERTION_SORT_CUTOFF )   {             insertionSort ( a ,  lo ,  hi );              return ;          }          // use median-of-3 as partitioning element          else   if   ( n  <=  MEDIAN_OF_3_CUTOFF )   {              int  m  =  median3 ( a ,  lo ,  lo  +  n / 2 ,  hi );             exch ( a ,  m ,  lo );          }          // use Tukey ninther as partitioning element          else    {              int  eps  =  n / 8 ;              int  mid  =  lo  +  n / 2 ;              int  m1  =  median3 ( a ,  lo ,  lo  +  eps ,  lo  +  eps  +  eps );              int  m2  =  median3 ( a ,  mid  -  eps ,  mid ,  mid  +  eps );              int  m3  =  median3 ( a ,  hi  -  eps  -  eps ,  hi  -  eps ,  hi );                int  ninther  =  median3 ( a ,  m1 ,  m2 ,  m3 );             exch ( a ,  ninther ,  lo );          }          // Bentley-McIlroy 3-way partitioning          int  i  =  lo ,  j  =  hi + 1 ;          int  p  =  lo ,  q  =  hi + 1 ;          Comparable  v  =  a [ lo ];          while   ( true )   {              while   ( less ( a [ ++ i ],  v ))                  if   ( i  ==  hi )   break ;              while   ( less ( v ,  a [ -- j ]))                  if   ( j  ==  lo )   break ;              // pointers cross              if   ( i  ==  j  &&  eq ( a [ i ],  v ))                 exch ( a ,   ++ p ,  i );              if   ( i  >=
 j
)
 
break
;

            exch
(
a
,
 i
,
 j
);

            
if
 
(
eq
(
a
[
i
],
 v
))
 exch
(
a
,
 
++
p
,
 i
);

            
if
 
(
eq
(
a
[
j
],
 v
))
 exch
(
a
,
 

q
,
 j
);

        
}

        i 
=
 j 
+
 
1
;

        
for
 
(
int
 k 
=
 lo
;
 k 
<=  p ;  k ++ )             exch ( a ,  k ,  j -- );          for   ( int  k  =  hi ;  k  >=
 q
;
 k

)

            exch
(
a
,
 k
,
 i
++
);

        sort
(
a
,
 lo
,
 j
);

        sort
(
a
,
 i
,
 hi
);

    
}

    
// sort from a[lo] to a[hi] using insertion sort

    
private
 
static
 
void
 insertionSort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
a
[
j
],
 a
[
j

1
]);
 j

)

                exch
(
a
,
 j
,
 j

1
);

    
}

    
// return the index of the median element among a[i], a[j], and a[k]

    
private
 
static
 
int
 median3
(
Comparable
[]
 a
,
 
int
 i
,
 
int
 j
,
 
int
 k
)
 
{

        
return
 
(
less
(
a
[
i
],
 a
[
j
])
 
?

               
(
less
(
a
[
j
],
 a
[
k
])
 
?
 j 
:
 less
(
a
[
i
],
 a
[
k
])
 
?
 k 
:
 i
)
 
:

               
(
less
(
a
[
k
],
 a
[
j
])
 
?
 j 
:
 less
(
a
[
k
],
 a
[
i
])
 
?
 k 
:
 i
));

    
}

   
/***************************************************************************

    *  Helper sorting functions.

    ***************************************************************************/

    

    
// is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          if   ( v  ==  w )   return   false ;      // optimization when reference equal          return  v . compareTo ( w )   <   0 ;      }      // does v == w ?      private   static   boolean  eq ( Comparable  v ,   Comparable  w )   {          if   ( v  ==  w )   return   true ;      // optimization when reference equal          return  v . compareTo ( w )   ==   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; quicksorts them      * (using an optimized version of quicksort);       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          QuickBentleyMcIlroy . sort ( a );          assert  isSorted ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/QuickFindUF.java edu/princeton/cs/algs4/QuickFindUF.java /******************************************************************************  *  Compilation:  javac QuickFindUF.java  *  Execution:  java QuickFindUF < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt  *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt  *                https://algs4.cs.princeton.edu/15uf/largeUF.txt  *  *  Quick-find algorithm.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  QuickFindUF} class represents a union–find data type

 *  (also known as the disjoint-sets data type).

 *  It supports the classic union and find operations,

 *  along with a count operation that returns the total number

 *  of sets.

 *  

 *  The union-find data type models a collection of sets containing

 *  n elements, with each element in exactly one set.

 *  The elements are named 0 through n–1.

 *  Initially, there are n sets, with each element in its

 *  own set. The cannonical elemement of a set

 *  (also known as the rootidentifier,

 *  leader, or set representative)

 *  is one distinguished element in the set. Here is a summary of

 *  the operations:

 *  

     *  

  • find(p) returns the canonical element

     *      of the set containing p. The find operation

     *      returns the same value for two elements if and only if

     *      they are in the same set.

     *  

  • union(pq) merges the set

     *      containing element p with the set containing

     *      element q. That is, if p and q

     *      are in different sets, replace these two sets

     *      with a new set that is the union of the two.

     *  

  • count() returns the number of sets.

     *  

 *  

 *  The canonical element of a set can change only when the set

 *  itself changes during a call to union—it cannot

 *  change during a call to either find or count.

 *  

 *  This implementation uses quick find.

 *  The constructor takes Θ(n) time, where n

 *  is the number of sites.

 *  The findconnected, and count

 *  operations take Θ(1) time; the union operation

 *  takes Θ(n) time.

 *  

 *  For alternative implementations of the same API, see

 *  {
@link
 UF}, {
@link
 QuickUnionUF}, and {
@link
 WeightedQuickUnionUF}.

 *  For additional documentation, see

 *  Section 1.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
QuickFindUF
 
{

    
private
 
int
[]
 id
;
    
// id[i] = component identifier of i

    
private
 
int
 count
;
   
// number of components

    
/**

     * Initializes an empty union-find data structure with

     * {
@code
 n} elements {
@code
 0} through {
@code
 n-1}. 

     * Initially, each elements is in its own set.

     *

     * 
@param
  n the number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n < 0}      */      public   QuickFindUF ( int  n )   {         count  =  n ;         id  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             id [ i ]   =  i ;      }      /**      * Returns the number of sets.      *      *  @return  the number of sets (between { @code  1} and { @code  n})      */      public   int  count ()   {          return  count ;      }         /**      * Returns the canonical element of the set containing element { @code  p}.      *      *  @param   p an element      *  @return  the canonical element of the set containing { @code  p}      *  @throws  IllegalArgumentException unless { @code  0 <= p < n}      */      public   int  find ( int  p )   {         validate ( p );          return  id [ p ];      }      // validate that p is a valid index      private   void  validate ( int  p )   {          int  n  =  id . length ;          if   ( p  <   0   ||  p  >=
 n
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index ”
 
+
 p 
+
 
” is not between 0 and ”
 
+
 
(
n

1
));

        
}

    
}

    
/**

     * Returns true if the two elements are in the same set.

     * 

     * 
@param
  p one element

     * 
@param
  q the other element

     * 
@return
 {
@code
 true} if {
@code
 p} and {
@code
 q} are in the same set;

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless

     *         both {
@code
 0 <= p < n} and { @code  0 <= q < n}      *  @deprecated  Replace with two calls to { @link  #find(int)}.      */     @ Deprecated      public   boolean  connected ( int  p ,   int  q )   {         validate ( p );         validate ( q );          return  id [ p ]   ==  id [ q ];      }         /**      * Merges the set containing element { @code  p} with the       * the set containing element { @code  q}.      *      *  @param   p one element      *  @param   q the other element      *  @throws  IllegalArgumentException unless      *         both { @code  0 <= p < n} and { @code  0 <= q < n}      */      public   void  union ( int  p ,   int  q )   {         validate ( p );         validate ( q );          int  pID  =  id [ p ];     // needed for correctness          int  qID  =  id [ q ];     // to reduce the number of array accesses          // p and q are already in the same component          if   ( pID  ==  qID )   return ;          for   ( int  i  =   0 ;  i  <  id . length ;  i ++ )              if   ( id [ i ]   ==  pID )  id [ i ]   =  qID ;         count -- ;      }      /**      * Reads in a an integer { @code  n} and a sequence of pairs of integers      * (between { @code  0} and { @code  n-1}) from standard input, where each integer      * in the pair represents some element;      * if the elements are in different sets, merge the two sets      * and print the pair to standard output.      *       *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  n  =   StdIn . readInt ();          QuickFindUF  uf  =   new   QuickFindUF ( n );          while   ( ! StdIn . isEmpty ())   {              int  p  =   StdIn . readInt ();              int  q  =   StdIn . readInt ();              if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;             uf . union ( p ,  q );              StdOut . println ( p  +   " "   +  q );          }          StdOut . println ( uf . count ()   +   " components" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Quick.java edu/princeton/cs/algs4/Quick.java /******************************************************************************  *  Compilation:  javac Quick.java  *  Execution:    java Quick < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt  *                https://algs4.cs.princeton.edu/23quicksort/words3.txt  *  *  Sorts a sequence of strings from standard input using quicksort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Quick < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *  *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *         *  % java Quick < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  *  *  Remark: For a type-safe version that uses static generics, see  *  *    https://algs4.cs.princeton.edu/23quicksort/QuickPedantic.java  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Quick} class provides static methods for sorting an  *  array and selecting the ith smallest element in an array using quicksort.  *  

 *  For additional documentation,

 *  see Section 2.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Quick
 
{

    
// This class should not be instantiated.

    
private
 
Quick
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
StdRandom
.
shuffle
(
a
);

        sort
(
a
,
 
0
,
 a
.
length 

 
1
);

        
assert
 isSorted
(
a
);

    
}

    
// quicksort the subarray from a[lo] to a[hi]

    
private
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{
 

        
if
 
(
hi 
<=  lo )   return ;          int  j  =  partition ( a ,  lo ,  hi );         sort ( a ,  lo ,  j - 1 );         sort ( a ,  j + 1 ,  hi );          assert  isSorted ( a ,  lo ,  hi );      }      // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]      // and return the index j.      private   static   int  partition ( Comparable []  a ,   int  lo ,   int  hi )   {          int  i  =  lo ;          int  j  =  hi  +   1 ;          Comparable  v  =  a [ lo ];          while   ( true )   {                // find item on lo to swap              while   ( less ( a [ ++ i ],  v ))   {                  if   ( i  ==  hi )   break ;              }              // find item on hi to swap              while   ( less ( v ,  a [ -- j ]))   {                  if   ( j  ==  lo )   break ;        // redundant since a[lo] acts as sentinel              }              // check if pointers cross              if   ( i  >=
 j
)
 
break
;

            exch
(
a
,
 i
,
 j
);

        
}

        
// put partitioning item v at a[j]

        exch
(
a
,
 lo
,
 j
);

        
// now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]          return  j ;      }      /**      * Rearranges the array so that { @code  a[k]} contains the kth smallest key;      * { @code  a[0]} through { @code  a[k-1]} are less than (or equal to) { @code  a[k]}; and      * { @code  a[k+1]} through { @code  a[n-1]} are greater than (or equal to) { @code  a[k]}.      *      *  @param   a the array      *  @param   k the rank of the key      *  @return  the key of rank { @code  k}      *  @throws  IllegalArgumentException unless { @code  0 <= k < a.length}      */      public   static   Comparable  select ( Comparable []  a ,   int  k )   {          if   ( k  <   0   ||  k  >=
 a
.
length
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index is not between 0 and ”
 
+
 a
.
length 
+
 
“: ”
 
+
 k
);

        
}

        
StdRandom
.
shuffle
(
a
);

        
int
 lo 
=
 
0
,
 hi 
=
 a
.
length 

 
1
;

        
while
 
(
hi 
>
 lo
)
 
{

            
int
 i 
=
 partition
(
a
,
 lo
,
 hi
);

            
if
      
(

>
 k
)
 hi 
=
 i 

 
1
;

            
else
 
if
 
(

<  k )  lo  =  i  +   1 ;              else   return  a [ i ];          }          return  a [ lo ];      }     /***************************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          if   ( v  ==  w )   return   false ;     // optimization when reference equals          return  v . compareTo ( w )   <   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length  -   1 );      }      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; quicksorts them;       * and prints them to standard output in ascending order.       * Shuffles the array and then prints the strings again to      * standard output, but this time, using the select method.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Quick . sort ( a );         show ( a );          assert  isSorted ( a );          // shuffle          StdRandom . shuffle ( a );          // display results again using select          StdOut . println ();          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              String  ith  =   ( String )   Quick . select ( a ,  i );              StdOut . println ( ith );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/QuickUnionUF.java edu/princeton/cs/algs4/QuickUnionUF.java /******************************************************************************  *  Compilation:  javac QuickUnionUF.java  *  Execution:  java QuickUnionUF < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt  *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt  *                https://algs4.cs.princeton.edu/15uf/largeUF.txt  *  *  Quick-union algorithm.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  QuickUnionUF} class represents a union–find data type

 *  (also known as the disjoint-sets data type).

 *  It supports the classic union and find operations,

 *  along with a count operation that returns the total number

 *  of sets.

 *  

 *  The union-find data type models a collection of sets containing

 *  n elements, with each element in exactly one set.

 *  The elements are named 0 through n–1.

 *  Initially, there are n sets, with each element in its

 *  own set. The cannonical elemement of a set

 *  (also known as the rootidentifier,

 *  leader, or set representative)

 *  is one distinguished element in the set. Here is a summary of

 *  the operations:

 *  

     *  

  • find(p) returns the canonical element

     *      of the set containing p. The find operation

     *      returns the same value for two elements if and only if

     *      they are in the same set.

     *  

  • union(pq) merges the set

     *      containing element p with the set containing

     *      element q. That is, if p and q

     *      are in different sets, replace these two sets

     *      with a new set that is the union of the two.

     *  

  • count() returns the number of sets.

     *  

 *  

 *  The canonical element of a set can change only when the set

 *  itself changes during a call to union—it cannot

 *  change during a call to either find or count.

 *  

 *  This implementation uses quick union.

 *  The constructor takes Θ(n) time, where

 *  n is the number of sites.

 *  The union and find operations take

 *  Θ(n) time in the worst case.

 *  The count operation takes Θ(1) time.

 *  

 *  For alternative implementations of the same API, see

 *  {
@link
 UF}, {
@link
 QuickFindUF}, and {
@link
 WeightedQuickUnionUF}.

 *  For additional documentation,

 *  see Section 1.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
QuickUnionUF
 
{

    
private
 
int
[]
 parent
;
  
// parent[i] = parent of i

    
private
 
int
 count
;
     
// number of components

    
/**

     * Initializes an empty union-find data structure with

     * {
@code
 n} elements {
@code
 0} through {
@code
 n-1}. 

     * Initially, each elements is in its own set.

     *

     * 
@param
  n the number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n < 0}      */      public   QuickUnionUF ( int  n )   {         parent  =   new   int [ n ];         count  =  n ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             parent [ i ]   =  i ;          }      }      /**      * Returns the number of sets.      *      *  @return  the number of sets (between { @code  1} and { @code  n})      */      public   int  count ()   {          return  count ;      }         /**      * Returns the canonical element of the set containing element { @code  p}.      *      *  @param   p an element      *  @return  the canonical element of the set containing { @code  p}      *  @throws  IllegalArgumentException unless { @code  0 <= p < n}      */      public   int  find ( int  p )   {         validate ( p );          while   ( p  !=  parent [ p ])             p  =  parent [ p ];          return  p ;      }      // validate that p is a valid index      private   void  validate ( int  p )   {          int  n  =  parent . length ;          if   ( p  <   0   ||  p  >=
 n
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index ”
 
+
 p 
+
 
” is not between 0 and ”
 
+
 
(
n

1
));

        
}

    
}

    
/**

     * Returns true if the two elements are in the same set.

     * 

     * 
@param
  p one element

     * 
@param
  q the other element

     * 
@return
 {
@code
 true} if {
@code
 p} and {
@code
 q} are in the same set;

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException unless

     *         both {
@code
 0 <= p < n} and { @code  0 <= q < n}      *  @deprecated  Replace with two calls to { @link  #find(int)}.      */     @ Deprecated      public   boolean  connected ( int  p ,   int  q )   {          return  find ( p )   ==  find ( q );      }      /**      * Merges the set containing element { @code  p} with the       * the set containing element { @code  q}.      *      *  @param   p one element      *  @param   q the other element      *  @throws  IllegalArgumentException unless      *         both { @code  0 <= p < n} and { @code  0 <= q < n}      */      public   void  union ( int  p ,   int  q )   {          int  rootP  =  find ( p );          int  rootQ  =  find ( q );          if   ( rootP  ==  rootQ )   return ;         parent [ rootP ]   =  rootQ ;           count -- ;      }      /**      * Reads in a an integer { @code  n} and a sequence of pairs of integers      * (between { @code  0} and { @code  n-1}) from standard input, where each integer      * in the pair represents some element;      * if the elements are in different sets, merge the two sets      * and print the pair to standard output.      *       *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  n  =   StdIn . readInt ();          QuickUnionUF  uf  =   new   QuickUnionUF ( n );          while   ( ! StdIn . isEmpty ())   {              int  p  =   StdIn . readInt ();              int  q  =   StdIn . readInt ();              if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;             uf . union ( p ,  q );              StdOut . println ( p  +   " "   +  q );          }          StdOut . println ( uf . count ()   +   " components" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/QuickX.java edu/princeton/cs/algs4/QuickX.java /******************************************************************************  *  Compilation:  javac QuickX.java  *  Execution:    java QuickX < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt  *                https://algs4.cs.princeton.edu/23quicksort/words3.txt  *    *  Uses the Hoare's 2-way partitioning scheme, chooses the partitioning  *  element using median-of-3, and cuts off to insertion sort.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  QuickX} class provides static methods for sorting an array  *  using an optimized version of quicksort (using Hoare's 2-way partitioning  *  algorithm, median-of-3 to choose the partitioning element, and cutoff  *  to insertion sort).  *  

 *  For additional documentation,

 *  see Section 2.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
QuickX
 
{

    
// cutoff to insertion sort, must be >= 1

    
private
 
static
 
final
 
int
 INSERTION_SORT_CUTOFF 
=
 
8
;

    
// This class should not be instantiated.

    
private
 
QuickX
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
// StdRandom.shuffle(a);

        sort
(
a
,
 
0
,
 a
.
length 

 
1
);

        
assert
 isSorted
(
a
);

    
}

    
// quicksort the subarray from a[lo] to a[hi]

    
private
 
static
 
void
 sort
(
Comparable
[]
 a
,
 
int
 lo
,
 
int
 hi
)
 
{
 

        
if
 
(
hi 
<=  lo )   return ;          // cutoff to insertion sort (Insertion.sort() uses half-open intervals)          int  n  =  hi  -  lo  +   1 ;          if   ( n  <=  INSERTION_SORT_CUTOFF )   {              Insertion . sort ( a ,  lo ,  hi  +   1 );              return ;          }          int  j  =  partition ( a ,  lo ,  hi );         sort ( a ,  lo ,  j - 1 );         sort ( a ,  j + 1 ,  hi );      }      // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]      // and return the index j.      private   static   int  partition ( Comparable []  a ,   int  lo ,   int  hi )   {          int  n  =  hi  -  lo  +   1 ;          int  m  =  median3 ( a ,  lo ,  lo  +  n / 2 ,  hi );         exch ( a ,  m ,  lo );          int  i  =  lo ;          int  j  =  hi  +   1 ;          Comparable  v  =  a [ lo ];          // a[lo] is unique largest element          while   ( less ( a [ ++ i ],  v ))   {              if   ( i  ==  hi )   {  exch ( a ,  lo ,  hi );   return  hi ;   }          }          // a[lo] is unique smallest element          while   ( less ( v ,  a [ -- j ]))   {              if   ( j  ==  lo  +   1 )   return  lo ;          }          // the main loop          while   ( i  <  j )   {               exch ( a ,  i ,  j );              while   ( less ( a [ ++ i ],  v ))   ;              while   ( less ( v ,  a [ -- j ]))   ;          }          // put partitioning item v at a[j]         exch ( a ,  lo ,  j );          // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]          return  j ;      }      // return the index of the median element among a[i], a[j], and a[k]      private   static   int  median3 ( Comparable []  a ,   int  i ,   int  j ,   int  k )   {          return   ( less ( a [ i ],  a [ j ])   ?                 ( less ( a [ j ],  a [ k ])   ?  j  :  less ( a [ i ],  a [ k ])   ?  k  :  i )   :                 ( less ( a [ k ],  a [ j ])   ?  j  :  less ( a [ k ],  a [ i ])   ?  k  :  i ));      }     /***************************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }      // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; quicksorts them      * (using an optimized version of 2-way quicksort);       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          QuickX . sort ( a );          assert  isSorted ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/RabinKarp.java edu/princeton/cs/algs4/RabinKarp.java /******************************************************************************  *  Compilation:  javac RabinKarp.java  *  Execution:    java RabinKarp pat txt  *  Dependencies: StdOut.java  *  *  Reads in two strings, the pattern and the input text, and  *  searches for the pattern in the input text using the  *  Las Vegas version of the Rabin-Karp algorithm.  *  *  % java RabinKarp abracadabra abacadabrabracabracadabrabrabracad  *  pattern: abracadabra  *  text:    abacadabrabracabracadabrabrabracad   *  match:                 abracadabra            *  *  % java RabinKarp rab abacadabrabracabracadabrabrabracad  *  pattern: rab  *  text:    abacadabrabracabracadabrabrabracad   *  match:           rab                           *  *  % java RabinKarp bcara abacadabrabracabracadabrabrabracad  *  pattern: bcara  *  text:         abacadabrabracabracadabrabrabracad   *  *  %  java RabinKarp rabrabracad abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad  *  pattern:                        rabrabracad  *  *  % java RabinKarp abacad abacadabrabracabracadabrabrabracad  *  text:    abacadabrabracabracadabrabrabracad  *  pattern: abacad  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . math . BigInteger ; import  java . util . Random ; /**  *  The { @code  RabinKarp} class finds the first occurrence of a pattern string  *  in a text string.  *  

 *  This implementation uses the Rabin-Karp algorithm.

 *  

 *  For additional documentation,

 *  see Section 5.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
RabinKarp
 
{

    
private
 
String
 pat
;
      
// the pattern  // needed only for Las Vegas

    
private
 
long
 patHash
;
    
// pattern hash value

    
private
 
int
 m
;
           
// pattern length

    
private
 
long
 q
;
          
// a large prime, small enough to avoid long overflow

    
private
 
int
 R
;
           
// radix

    
private
 
long
 RM
;
         
// R^(M-1) % Q

    
/**

     * Preprocesses the pattern string.

     *

     * 
@param
 pattern the pattern string

     * 
@param
 R the alphabet size

     */

    
public
 
RabinKarp
(
char
[]
 pattern
,
 
int
 R
)
 
{

        
this
.
pat 
=
 
String
.
valueOf
(
pattern
);

        
this
.

=
 R
;
        

        
throw
 
new
 
UnsupportedOperationException
(
“Operation not supported yet”
);

    
}

    
/**

     * Preprocesses the pattern string.

     *

     * 
@param
 pat the pattern string

     */

    
public
 
RabinKarp
(
String
 pat
)
 
{

        
this
.
pat 
=
 pat
;
      
// save pattern (needed only for Las Vegas)

        R 
=
 
256
;

        m 
=
 pat
.
length
();

        q 
=
 longRandomPrime
();

        
// precompute R^(m-1) % q for use in removing leading digit

        RM 
=
 
1
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  m - 1 ;  i ++ )             RM  =   ( R  *  RM )   %  q ;         patHash  =  hash ( pat ,  m );      }        // Compute hash for key[0..m-1].       private   long  hash ( String  key ,   int  m )   {            long  h  =   0 ;            for   ( int  j  =   0 ;  j  <  m ;  j ++ )               h  =   ( R  *  h  +  key . charAt ( j ))   %  q ;          return  h ;      }      // Las Vegas version: does pat[] match txt[i..i-m+1] ?      private   boolean  check ( String  txt ,   int  i )   {          for   ( int  j  =   0 ;  j  <  m ;  j ++ )                if   ( pat . charAt ( j )   !=  txt . charAt ( i  +  j ))                    return   false ;            return   true ;      }      // Monte Carlo version: always return true      // private boolean check(int i) {      //    return true;      //}        /**      * Returns the index of the first occurrrence of the pattern string      * in the text string.      *      *  @param   txt the text string      *  @return  the index of the first occurrence of the pattern string      *         in the text string; n if no such match      */      public   int  search ( String  txt )   {          int  n  =  txt . length ();            if   ( n  <  m )   return  n ;          long  txtHash  =  hash ( txt ,  m );            // check for match at offset 0          if   (( patHash  ==  txtHash )   &&  check ( txt ,   0 ))              return   0 ;          // check for hash match; if hash match, check for exact match          for   ( int  i  =  m ;  i  <  n ;  i ++ )   {              // Remove leading digit, add trailing digit, check for match.              txtHash  =   ( txtHash  +  q  -  RM * txt . charAt ( i - m )   %  q )   %  q ;               txtHash  =   ( txtHash * R  +  txt . charAt ( i ))   %  q ;                // match              int  offset  =  i  -  m  +   1 ;              if   (( patHash  ==  txtHash )   &&  check ( txt ,  offset ))                  return  offset ;          }          // no match          return  n ;      }      // a random 31-bit prime      private   static   long  longRandomPrime ()   {          BigInteger  prime  =   BigInteger . probablePrime ( 31 ,   new   Random ());          return  prime . longValue ();      }      /**       * Takes a pattern string and an input string as command-line arguments;      * searches for the pattern string in the text string; and prints      * the first occurrence of the pattern string in the text string.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String  pat  =  args [ 0 ];          String  txt  =  args [ 1 ];          RabinKarp  searcher  =   new   RabinKarp ( pat );          int  offset  =  searcher . search ( txt );          // print results          StdOut . println ( "text:    "   +  txt );          // from brute force search method 1          StdOut . print ( "pattern: " );          for   ( int  i  =   0 ;  i  <  offset ;  i ++ )              StdOut . print ( " " );          StdOut . println ( pat );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/RandomSeq.java edu/princeton/cs/algs4/RandomSeq.java /******************************************************************************  *  Compilation:  javac RandomSeq.java  *  Execution:    java RandomSeq n lo hi  *  Dependencies: StdOut.java  *  *  Prints N numbers between lo and hi.  *  *  % java RandomSeq 5 100.0 200.0  *  123.43  *  153.13  *  144.38  *  155.18  *  104.02  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  RandomSeq} class is a client that prints out a pseudorandom  *  sequence of real numbers in a given range.  *  

 *  For additional documentation, see Section 1.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
RandomSeq
 
{
 

    
// this class should not be instantiated

    
private
 
RandomSeq
()
 
{
 
}

    
/**

     * Reads in two command-line arguments lo and hi and prints n uniformly

     * random real numbers in [lo, hi) to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// command-line arguments

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
// for backward compatibility with Intro to Programming in Java version of RandomSeq

        
if
 
(
args
.
length 
==
 
1
)
 
{

            
// generate and print n numbers between 0.0 and 1.0

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {                  double  x  =   StdRandom . uniform ();                  StdOut . println ( x );              }          }          else   if   ( args . length  ==   3 )   {              double  lo  =   Double . parseDouble ( args [ 1 ]);              double  hi  =   Double . parseDouble ( args [ 2 ]);              // generate and print n numbers between lo and hi              for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {                  double  x  =   StdRandom . uniform ( lo ,  hi );                  StdOut . printf ( "%.2f\n" ,  x );              }          }          else   {              throw   new   IllegalArgumentException ( "Invalid number of arguments" );          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/RectHV.java edu/princeton/cs/algs4/RectHV.java /******************************************************************************  *  Compilation:  javac RectHV.java  *  Execution:    none  *  Dependencies: Point2D.java  *  *  Immutable data type for 2D axis-aligned rectangle.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  RectHV} class is an immutable data type to encapsulate a  *  two-dimensional axis-aligned rectagle with real-value coordinates.  *  The rectangle is closed—it includes the points on the boundary.

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
RectHV
 
{

    
private
 
final
 
double
 xmin
,
 ymin
;
   
// minimum x- and y-coordinates

    
private
 
final
 
double
 xmax
,
 ymax
;
   
// maximum x- and y-coordinates

    
/**

     * Initializes a new rectangle [xminxmax]

     * x [yminymax].

     *

     * 
@param
  xmin the x-coordinate of the lower-left endpoint

     * 
@param
  xmax the x-coordinate of the upper-right endpoint

     * 
@param
  ymin the y-coordinate of the lower-left endpoint

     * 
@param
  ymax the y-coordinate of the upper-right endpoint

     * 
@throws
 IllegalArgumentException if any of {
@code
 xmin},

     *         {
@code
 xmax}, {
@code
 ymin}, or {
@code
 ymax}

     *         is {
@code
 Double.NaN}.

     * 
@throws
 IllegalArgumentException if {
@code
 xmax < xmin} or { @code  ymax < ymin}.      */      public   RectHV ( double  xmin ,   double  ymin ,   double  xmax ,   double  ymax )   {          this . xmin  =  xmin ;          this . ymin  =  ymin ;          this . xmax  =  xmax ;          this . ymax  =  ymax ;          if   ( Double . isNaN ( xmin )   ||   Double . isNaN ( xmax ))   {              throw   new   IllegalArgumentException ( "x-coordinate is NaN: "   +  toString ());          }          if   ( Double . isNaN ( ymin )   ||   Double . isNaN ( ymax ))   {              throw   new   IllegalArgumentException ( "y-coordinate is NaN: "   +  toString ());          }          if   ( xmax  <  xmin )   {              throw   new   IllegalArgumentException ( "xmax < xmin: "   +  toString ());          }          if   ( ymax  <  ymin )   {              throw   new   IllegalArgumentException ( "ymax < ymin: "   +  toString ());          }      }      /**      * Returns the minimum x-coordinate of any point in this rectangle.

     *

     * 
@return
 the minimum x-coordinate of any point in this rectangle

     */

    
public
 
double
 xmin
()
 
{

        
return
 xmin
;

    
}

    
/**

     * Returns the maximum x-coordinate of any point in this rectangle.

     *

     * 
@return
 the maximum x-coordinate of any point in this rectangle

     */

    
public
 
double
 xmax
()
 
{

        
return
 xmax
;

    
}

    
/**

     * Returns the minimum y-coordinate of any point in this rectangle.

     *

     * 
@return
 the minimum y-coordinate of any point in this rectangle

     */

    
public
 
double
 ymin
()
 
{

        
return
 ymin
;

    
}

    
/**

     * Returns the maximum y-coordinate of any point in this rectangle.

     *

     * 
@return
 the maximum y-coordinate of any point in this rectangle

     */

    
public
 
double
 ymax
()
 
{

        
return
 ymax
;

    
}

    
/**

     * Returns the width of this rectangle.

     *

     * 
@return
 the width of this rectangle {
@code
 xmax – xmin}

     */

    
public
 
double
 width
()
 
{

        
return
 xmax 

 xmin
;

    
}

    
/**

     * Returns the height of this rectangle.

     *

     * 
@return
 the height of this rectangle {
@code
 ymax – ymin}

     */

    
public
 
double
 height
()
 
{

        
return
 ymax 

 ymin
;

    
}

    
/**

     * Returns true if the two rectangles intersect. This includes

     * improper intersections (at points on the boundary

     * of each rectangle) and nested intersctions

     * (when one rectangle is contained inside the other)

     *

     * 
@param
  that the other rectangle

     * 
@return
 {
@code
 true} if this rectangle intersect the argument

               rectangle at one or more points

     */

    
public
 
boolean
 intersects
(
RectHV
 that
)
 
{

        
return
 
this
.
xmax 
>=
 that
.
xmin 
&&
 
this
.
ymax 
>=
 that
.
ymin

            
&&
 that
.
xmax 
>=
 
this
.
xmin 
&&
 that
.
ymax 
>=
 
this
.
ymin
;

    
}

    
/**

     * Returns true if this rectangle contain the point.

     * 
@param
  p the point

     * 
@return
 {
@code
 true} if this rectangle contain the point {
@code
 p},

               possibly at the boundary; {
@code
 false} otherwise

     */

    
public
 
boolean
 contains
(
Point2D
 p
)
 
{

        
return
 
(
p
.
x
()
 
>=
 xmin
)
 
&&
 
(
p
.
x
()
 
<=  xmax )              &&   ( p . y ()   >=
 ymin
)
 
&&
 
(
p
.
y
()
 
<=  ymax );      }      /**      * Returns the Euclidean distance between this rectangle and the point { @code  p}.      *      *  @param   p the point      *  @return  the Euclidean distance between the point { @code  p} and the closest point                on this rectangle; 0 if the point is contained in this rectangle      */      public   double  distanceTo ( Point2D  p )   {          return   Math . sqrt ( this . distanceSquaredTo ( p ));      }      /**      * Returns the square of the Euclidean distance between this rectangle and the point { @code  p}.      *      *  @param   p the point      *  @return  the square of the Euclidean distance between the point { @code  p} and      *         the closest point on this rectangle; 0 if the point is contained      *         in this rectangle      */      public   double  distanceSquaredTo ( Point2D  p )   {          double  dx  =   0.0 ,  dy  =   0.0 ;          if        ( p . x ()   <  xmin )  dx  =  p . x ()   -  xmin ;          else   if   ( p . x ()   >
 xmax
)
 dx 
=
 p
.
x
()
 

 xmax
;

        
if
      
(
p
.
y
()
 
<  ymin )  dy  =  p . y ()   -  ymin ;          else   if   ( p . y ()   >
 ymax
)
 dy 
=
 p
.
y
()
 

 ymax
;

        
return
 dx
*
dx 
+
 dy
*
dy
;

    
}

    
/**

     * Compares this rectangle to the specified rectangle.

     *

     * 
@param
  other the other rectangle

     * 
@return
 {
@code
 true} if this rectangle equals {
@code
 other};

     *         {
@code
 false} otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
RectHV
 that 
=
 
(
RectHV
)
 other
;

        
if
 
(
this
.
xmin 
!=
 that
.
xmin
)
 
return
 
false
;

        
if
 
(
this
.
ymin 
!=
 that
.
ymin
)
 
return
 
false
;

        
if
 
(
this
.
xmax 
!=
 that
.
xmax
)
 
return
 
false
;

        
if
 
(
this
.
ymax 
!=
 that
.
ymax
)
 
return
 
false
;

        
return
 
true
;

    
}

    
/**

     * Returns an integer hash code for this rectangle.

     * 
@return
 an integer hash code for this rectangle

     */

    @
Override

    
public
 
int
 hashCode
()
 
{

        
int
 hash1 
=
 
((
Double
)
 xmin
).
hashCode
();

        
int
 hash2 
=
 
((
Double
)
 ymin
).
hashCode
();

        
int
 hash3 
=
 
((
Double
)
 xmax
).
hashCode
();

        
int
 hash4 
=
 
((
Double
)
 ymax
).
hashCode
();

        
return
 
31
*
(
31
*
(
31
*
hash1 
+
 hash2
)
 
+
 hash3
)
 
+
 hash4
;

    
}

    
/**

     * Returns a string representation of this rectangle.

     *

     * 
@return
 a string representation of this rectangle, using the format

     *         {
@code
 [xmin, xmax] x [ymin, ymax]}

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
return
 
“[”
 
+
 xmin 
+
 
“, ”
 
+
 xmax 
+
 
“] x [”
 
+
 ymin 
+
 
“, ”
 
+
 ymax 
+
 
“]”
;

    
}

    
/**

     * Draws this rectangle to standard draw.

     */

    
public
 
void
 draw
()
 
{

        
StdDraw
.
line
(
xmin
,
 ymin
,
 xmax
,
 ymin
);

        
StdDraw
.
line
(
xmax
,
 ymin
,
 xmax
,
 ymax
);

        
StdDraw
.
line
(
xmax
,
 ymax
,
 xmin
,
 ymax
);

        
StdDraw
.
line
(
xmin
,
 ymax
,
 xmin
,
 ymin
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/RedBlackBST.java
edu/princeton/cs/algs4/RedBlackBST.java
/******************************************************************************

 *  Compilation:  javac RedBlackBST.java

 *  Execution:    java RedBlackBST < input.txt  *  Dependencies: StdIn.java StdOut.java    *  Data files:   https://algs4.cs.princeton.edu/33balanced/tinyST.txt    *      *  A symbol table implemented using a left-leaning red-black BST.  *  This is the 2-3 version.  *  *  Note: commented out assertions because DrJava now enables assertions  *        by default.  *  *  % more tinyST.txt  *  S E A R C H E X A M P L E  *    *  % java RedBlackBST < tinyST.txt  *  A 8  *  C 4  *  E 12  *  H 5  *  L 11  *  M 9  *  P 10  *  R 3  *  S 0  *  X 7  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . NoSuchElementException ; /**  *  The { @code  BST} class represents an ordered symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides ordered methods for finding the minimum,

 *  maximumfloor, and ceiling.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  

 *  This implementation uses a left-leaning red-black BST

 *  The putgetcontainsremove,

 *  minimummaximumceilingfloor,

 *  rank, and select operations each take

 *  Θ(log n) time in the worst case, where n is the

 *  number of key-value pairs in the symbol table.

 *  The size, and is-empty operations take Θ(1) time.

 *  The keys methods take

 *  O(log n + m) time, where m is

 *  the number of keys returned by the iterator.

 *  Construction takes Θ(1) time.

 *  

 *  For alternative implementations of the symbol table API, see {
@link
 ST},

 *  {
@link
 BinarySearchST}, {
@link
 SequentialSearchST}, {
@link
 BST},

 *  {
@link
 SeparateChainingHashST}, {
@link
 LinearProbingHashST}, and

 *  {
@link
 AVLTreeST}.

 *  For additional documentation, see

 *  Section 3.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
RedBlackBST
< Key   extends   Comparable < Key >
,
 
Value
>
 
{

    
private
 
static
 
final
 
boolean
 RED   
=
 
true
;

    
private
 
static
 
final
 
boolean
 BLACK 
=
 
false
;

    
private
 
Node
 root
;
     
// root of the BST

    
// BST helper node data type

    
private
 
class
 
Node
 
{

        
private
 
Key
 key
;
           
// key

        
private
 
Value
 val
;
         
// associated data

        
private
 
Node
 left
,
 right
;
  
// links to left and right subtrees

        
private
 
boolean
 color
;
     
// color of parent link

        
private
 
int
 size
;
          
// subtree count

        
public
 
Node
(
Key
 key
,
 
Value
 val
,
 
boolean
 color
,
 
int
 size
)
 
{

            
this
.
key 
=
 key
;

            
this
.
val 
=
 val
;

            
this
.
color 
=
 color
;

            
this
.
size 
=
 size
;

        
}

    
}

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
RedBlackBST
()
 
{

    
}

   
/***************************************************************************

    *  Node helper methods.

    ***************************************************************************/

    
// is node x red; false if x is null ?

    
private
 
boolean
 isRed
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
false
;

        
return
 x
.
color 
==
 RED
;

    
}

    
// number of node in subtree rooted at x; 0 if x is null

    
private
 
int
 size
(
Node
 x
)
 
{

        
if
 
(

==
 
null
)
 
return
 
0
;

        
return
 x
.
size
;

    
}
 

    
/**

     * Returns the number of key-value pairs in this symbol table.

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 size
(
root
);

    
}

   
/**

     * Is this symbol table empty?

     * 
@return
 {
@code
 true} if this symbol table is empty and {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 root 
==
 
null
;

    
}

   
/***************************************************************************

    *  Standard BST search.

    ***************************************************************************/

    
/**

     * Returns the value associated with the given key.

     * 
@param
 key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *     and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);

        
return
 get
(
root
,
 key
);

    
}

    
// value associated with the given key in subtree rooted at x; null if no such key

    
private
 
Value
 get
(
Node
 x
,
 
Key
 key
)
 
{

        
while
 
(

!=
 
null
)
 
{

            
int
 cmp 
=
 key
.
compareTo
(
x
.
key
);

            
if
      
(
cmp 
<   0 )  x  =  x . left ;              else   if   ( cmp  >
 
0
)
 x 
=
 x
.
right
;

            
else
              
return
 x
.
val
;

        
}

        
return
 
null
;

    
}

    
/**

     * Does this symbol table contain the given key?

     * 
@param
 key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key} and

     *     {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
return
 get
(
key
)
 
!=
 
null
;

    
}

   
/***************************************************************************

    *  Red-black tree insertion.

    ***************************************************************************/

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting the old 

     * value with the new value if the symbol table already contains the specified key.

     * Deletes the specified key (and its associated value) from this symbol table

     * if the specified value is {
@code
 null}.

     *

     * 
@param
 key the key

     * 
@param
 val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to put() is null”
);

        
if
 
(
val 
==
 
null
)
 
{

            delete
(
key
);

            
return
;

        
}

        root 
=
 put
(
root
,
 key
,
 val
);

        root
.
color 
=
 BLACK
;

        
// assert check();

    
}

    
// insert the key-value pair in the subtree rooted at h

    
private
 
Node
 put
(
Node
 h
,
 
Key
 key
,
 
Value
 val
)
 
{
 

        
if
 
(

==
 
null
)
 
return
 
new
 
Node
(
key
,
 val
,
 RED
,
 
1
);

        
int
 cmp 
=
 key
.
compareTo
(
h
.
key
);

        
if
      
(
cmp 
<   0 )  h . left   =  put ( h . left ,   key ,  val );            else   if   ( cmp  >
 
0
)
 h
.
right 
=
 put
(
h
.
right
,
 key
,
 val
);
 

        
else
              h
.
val   
=
 val
;

        
// fix-up any right-leaning links

        
if
 
(
isRed
(
h
.
right
)
 
&&
 
!
isRed
(
h
.
left
))
      h 
=
 rotateLeft
(
h
);

        
if
 
(
isRed
(
h
.
left
)
  
&&
  isRed
(
h
.
left
.
left
))
 h 
=
 rotateRight
(
h
);

        
if
 
(
isRed
(
h
.
left
)
  
&&
  isRed
(
h
.
right
))
     flipColors
(
h
);

        h
.
size 
=
 size
(
h
.
left
)
 
+
 size
(
h
.
right
)
 
+
 
1
;

        
return
 h
;

    
}

   
/***************************************************************************

    *  Red-black tree deletion.

    ***************************************************************************/

    
/**

     * Removes the smallest key and associated value from the symbol table.

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMin
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“BST underflow”
);

        
// if both children of root are black, set root to red

        
if
 
(
!
isRed
(
root
.
left
)
 
&&
 
!
isRed
(
root
.
right
))

            root
.
color 
=
 RED
;

        root 
=
 deleteMin
(
root
);

        
if
 
(
!
isEmpty
())
 root
.
color 
=
 BLACK
;

        
// assert check();

    
}

    
// delete the key-value pair with the minimum key rooted at h

    
private
 
Node
 deleteMin
(
Node
 h
)
 
{
 

        
if
 
(
h
.
left 
==
 
null
)

            
return
 
null
;

        
if
 
(
!
isRed
(
h
.
left
)
 
&&
 
!
isRed
(
h
.
left
.
left
))

            h 
=
 moveRedLeft
(
h
);

        h
.
left 
=
 deleteMin
(
h
.
left
);

        
return
 balance
(
h
);

    
}

    
/**

     * Removes the largest key and associated value from the symbol table.

     * 
@throws
 NoSuchElementException if the symbol table is empty

     */

    
public
 
void
 deleteMax
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“BST underflow”
);

        
// if both children of root are black, set root to red

        
if
 
(
!
isRed
(
root
.
left
)
 
&&
 
!
isRed
(
root
.
right
))

            root
.
color 
=
 RED
;

        root 
=
 deleteMax
(
root
);

        
if
 
(
!
isEmpty
())
 root
.
color 
=
 BLACK
;

        
// assert check();

    
}

    
// delete the key-value pair with the maximum key rooted at h

    
private
 
Node
 deleteMax
(
Node
 h
)
 
{
 

        
if
 
(
isRed
(
h
.
left
))

            h 
=
 rotateRight
(
h
);

        
if
 
(
h
.
right 
==
 
null
)

            
return
 
null
;

        
if
 
(
!
isRed
(
h
.
right
)
 
&&
 
!
isRed
(
h
.
right
.
left
))

            h 
=
 moveRedRight
(
h
);

        h
.
right 
=
 deleteMax
(
h
.
right
);

        
return
 balance
(
h
);

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).    

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{
 

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to delete() is null”
);

        
if
 
(
!
contains
(
key
))
 
return
;

        
// if both children of root are black, set root to red

        
if
 
(
!
isRed
(
root
.
left
)
 
&&
 
!
isRed
(
root
.
right
))

            root
.
color 
=
 RED
;

        root 
=
 delete
(
root
,
 key
);

        
if
 
(
!
isEmpty
())
 root
.
color 
=
 BLACK
;

        
// assert check();

    
}

    
// delete the key-value pair with the given key rooted at h

    
private
 
Node
 delete
(
Node
 h
,
 
Key
 key
)
 
{
 

        
// assert get(h, key) != null;

        
if
 
(
key
.
compareTo
(
h
.
key
)
 
<   0 )    {              if   ( ! isRed ( h . left )   &&   ! isRed ( h . left . left ))                 h  =  moveRedLeft ( h );             h . left  =  delete ( h . left ,  key );          }          else   {              if   ( isRed ( h . left ))                 h  =  rotateRight ( h );              if   ( key . compareTo ( h . key )   ==   0   &&   ( h . right  ==   null ))                  return   null ;              if   ( ! isRed ( h . right )   &&   ! isRed ( h . right . left ))                 h  =  moveRedRight ( h );              if   ( key . compareTo ( h . key )   ==   0 )   {                  Node  x  =  min ( h . right );                 h . key  =  x . key ;                 h . val  =  x . val ;                  // h.val = get(h.right, min(h.right).key);                  // h.key = min(h.right).key;                 h . right  =  deleteMin ( h . right );              }              else  h . right  =  delete ( h . right ,  key );          }          return  balance ( h );      }     /***************************************************************************     *  Red-black tree helper functions.     ***************************************************************************/      // make a left-leaning link lean to the right      private   Node  rotateRight ( Node  h )   {          // assert (h != null) && isRed(h.left);          Node  x  =  h . left ;         h . left  =  x . right ;         x . right  =  h ;         x . color  =  x . right . color ;         x . right . color  =  RED ;         x . size  =  h . size ;         h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;          return  x ;      }      // make a right-leaning link lean to the left      private   Node  rotateLeft ( Node  h )   {          // assert (h != null) && isRed(h.right);          Node  x  =  h . right ;         h . right  =  x . left ;         x . left  =  h ;         x . color  =  x . left . color ;         x . left . color  =  RED ;         x . size  =  h . size ;         h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;          return  x ;      }      // flip the colors of a node and its two children      private   void  flipColors ( Node  h )   {          // h must have opposite color of its two children          // assert (h != null) && (h.left != null) && (h.right != null);          // assert (!isRed(h) &&  isRed(h.left) &&  isRed(h.right))          //    || (isRed(h)  && !isRed(h.left) && !isRed(h.right));         h . color  =   ! h . color ;         h . left . color  =   ! h . left . color ;         h . right . color  =   ! h . right . color ;      }      // Assuming that h is red and both h.left and h.left.left      // are black, make h.left or one of its children red.      private   Node  moveRedLeft ( Node  h )   {          // assert (h != null);          // assert isRed(h) && !isRed(h.left) && !isRed(h.left.left);         flipColors ( h );          if   ( isRed ( h . right . left ))   {               h . right  =  rotateRight ( h . right );             h  =  rotateLeft ( h );             flipColors ( h );          }          return  h ;      }      // Assuming that h is red and both h.right and h.right.left      // are black, make h.right or one of its children red.      private   Node  moveRedRight ( Node  h )   {          // assert (h != null);          // assert isRed(h) && !isRed(h.right) && !isRed(h.right.left);         flipColors ( h );          if   ( isRed ( h . left . left ))   {               h  =  rotateRight ( h );             flipColors ( h );          }          return  h ;      }      // restore red-black tree invariant      private   Node  balance ( Node  h )   {          // assert (h != null);          if   ( isRed ( h . right ))                       h  =  rotateLeft ( h );          if   ( isRed ( h . left )   &&  isRed ( h . left . left ))  h  =  rotateRight ( h );          if   ( isRed ( h . left )   &&  isRed ( h . right ))      flipColors ( h );         h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;          return  h ;      }     /***************************************************************************     *  Utility functions.     ***************************************************************************/      /**      * Returns the height of the BST (for debugging).      *  @return  the height of the BST (a 1-node tree has height 0)      */      public   int  height ()   {          return  height ( root );      }      private   int  height ( Node  x )   {          if   ( x  ==   null )   return   - 1 ;          return   1   +   Math . max ( height ( x . left ),  height ( x . right ));      }     /***************************************************************************     *  Ordered symbol table methods.     ***************************************************************************/      /**      * Returns the smallest key in the symbol table.      *  @return  the smallest key in the symbol table      *  @throws  NoSuchElementException if the symbol table is empty      */      public   Key  min ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls min() with empty symbol table" );          return  min ( root ). key ;      }        // the smallest key in subtree rooted at x; null if no such key      private   Node  min ( Node  x )   {            // assert x != null;          if   ( x . left  ==   null )   return  x ;            else                  return  min ( x . left );        }        /**      * Returns the largest key in the symbol table.      *  @return  the largest key in the symbol table      *  @throws  NoSuchElementException if the symbol table is empty      */      public   Key  max ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls max() with empty symbol table" );          return  max ( root ). key ;      }        // the largest key in the subtree rooted at x; null if no such key      private   Node  max ( Node  x )   {            // assert x != null;          if   ( x . right  ==   null )   return  x ;            else                   return  max ( x . right );        }        /**      * Returns the largest key in the symbol table less than or equal to { @code  key}.      *  @param  key the key      *  @return  the largest key in the symbol table less than or equal to { @code  key}      *  @throws  NoSuchElementException if there is no such key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Key  floor ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );          if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls floor() with empty symbol table" );          Node  x  =  floor ( root ,  key );          if   ( x  ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );          else             return  x . key ;      }           // the largest key in the subtree rooted at x less than or equal to the given key      private   Node  floor ( Node  x ,   Key  key )   {          if   ( x  ==   null )   return   null ;          int  cmp  =  key . compareTo ( x . key );          if   ( cmp  ==   0 )   return  x ;          if   ( cmp  <   0 )    return  floor ( x . left ,  key );          Node  t  =  floor ( x . right ,  key );          if   ( t  !=   null )   return  t ;            else             return  x ;      }      /**      * Returns the smallest key in the symbol table greater than or equal to { @code  key}.      *  @param  key the key      *  @return  the smallest key in the symbol table greater than or equal to { @code  key}      *  @throws  NoSuchElementException if there is no such key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Key  ceiling ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );          if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls ceiling() with empty symbol table" );          Node  x  =  ceiling ( root ,  key );          if   ( x  ==   null )   throw   new   NoSuchElementException ( "argument to ceiling() is too small" );          else             return  x . key ;         }      // the smallest key in the subtree rooted at x greater than or equal to the given key      private   Node  ceiling ( Node  x ,   Key  key )   {             if   ( x  ==   null )   return   null ;          int  cmp  =  key . compareTo ( x . key );          if   ( cmp  ==   0 )   return  x ;          if   ( cmp  >
 
0
)
  
return
 ceiling
(
x
.
right
,
 key
);

        
Node
 t 
=
 ceiling
(
x
.
left
,
 key
);

        
if
 
(

!=
 
null
)
 
return
 t
;
 

        
else
           
return
 x
;

    
}

    
/**

     * Return the key in the symbol table whose rank is {
@code
 k}.

     * This is the (k+1)st smallest key in the symbol table. 

     *

     * 
@param
  k the order statistic

     * 
@return
 the key in the symbol table of rank {
@code
 k}

     * 
@throws
 IllegalArgumentException unless {
@code
 k} is between 0 and

     *        n–1

     */

    
public
 
Key
 select
(
int
 k
)
 
{

        
if
 
(

<   0   ||  k  >=
 size
())
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument to select() is invalid: ”
 
+
 k
);

        
}

        
Node
 x 
=
 select
(
root
,
 k
);

        
return
 x
.
key
;

    
}

    
// the key of rank k in the subtree rooted at x

    
private
 
Node
 select
(
Node
 x
,
 
int
 k
)
 
{

        
// assert x != null;

        
// assert k >= 0 && k < size(x);          int  t  =  size ( x . left );            if        ( t  >
 k
)
 
return
 select
(
x
.
left
,
  k
);
 

        
else
 
if
 
(

<  k )   return  select ( x . right ,  k - t - 1 );            else              return  x ;        }        /**      * Return the number of keys in the symbol table strictly less than { @code  key}.      *  @param  key the key      *  @return  the number of keys in the symbol table strictly less than { @code  key}      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   int  rank ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );          return  rank ( key ,  root );      }        // number of keys less than key in the subtree rooted at x      private   int  rank ( Key  key ,   Node  x )   {          if   ( x  ==   null )   return   0 ;            int  cmp  =  key . compareTo ( x . key );            if        ( cmp  <   0 )   return  rank ( key ,  x . left );            else   if   ( cmp  >
 
0
)
 
return
 
1
 
+
 size
(
x
.
left
)
 
+
 rank
(
key
,
 x
.
right
);
 

        
else
              
return
 size
(
x
.
left
);
 

    
}
 

   
/***************************************************************************

    *  Range count and range search.

    ***************************************************************************/

    
/**

     * Returns all keys in the symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     * 
@return
 all keys in the symbol table as an {
@code
 Iterable}

     */

    
public
 
Iterable
< Key >
 keys
()
 
{

        
if
 
(
isEmpty
())
 
return
 
new
 
Queue
< Key >
();

        
return
 keys
(
min
(),
 max
());

    
}

    
/**

     * Returns all keys in the symbol table in the given range,

     * as an {
@code
 Iterable}.

     *

     * 
@param
  lo minimum endpoint

     * 
@param
  hi maximum endpoint

     * 
@return
 all keys in the symbol table between {
@code
 lo} 

     *    (inclusive) and {
@code
 hi} (inclusive) as an {
@code
 Iterable}

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *    is {
@code
 null}

     */

    
public
 
Iterable
< Key >
 keys
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to keys() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to keys() is null”
);

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        
// if (isEmpty() || lo.compareTo(hi) > 0) return queue;

        keys
(
root
,
 queue
,
 lo
,
 hi
);

        
return
 queue
;

    
}
 

    
// add the keys between lo and hi in the subtree rooted at x

    
// to the queue

    
private
 
void
 keys
(
Node
 x
,
 
Queue
< Key >
 queue
,
 
Key
 lo
,
 
Key
 hi
)
 
{
 

        
if
 
(

==
 
null
)
 
return
;
 

        
int
 cmplo 
=
 lo
.
compareTo
(
x
.
key
);
 

        
int
 cmphi 
=
 hi
.
compareTo
(
x
.
key
);
 

        
if
 
(
cmplo 
<   0 )  keys ( x . left ,  queue ,  lo ,  hi );            if   ( cmplo  <=   0   &&  cmphi  >=
 
0
)
 queue
.
enqueue
(
x
.
key
);
 

        
if
 
(
cmphi 
>
 
0
)
 keys
(
x
.
right
,
 queue
,
 lo
,
 hi
);
 

    
}
 

    
/**

     * Returns the number of keys in the symbol table in the given range.

     *

     * 
@param
  lo minimum endpoint

     * 
@param
  hi maximum endpoint

     * 
@return
 the number of keys in the symbol table between {
@code
 lo} 

     *    (inclusive) and {
@code
 hi} (inclusive)

     * 
@throws
 IllegalArgumentException if either {
@code
 lo} or {
@code
 hi}

     *    is {
@code
 null}

     */

    
public
 
int
 size
(
Key
 lo
,
 
Key
 hi
)
 
{

        
if
 
(
lo 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to size() is null”
);

        
if
 
(
hi 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“second argument to size() is null”
);

        
if
 
(
lo
.
compareTo
(
hi
)
 
>
 
0
)
 
return
 
0
;

        
if
 
(
contains
(
hi
))
 
return
 rank
(
hi
)
 

 rank
(
lo
)
 
+
 
1
;

        
else
              
return
 rank
(
hi
)
 

 rank
(
lo
);

    }

   /***************************************************************************    *  Check integrity of red-black tree data structure.    ***************************************************************************/

    private boolean check() {

        if (!isBST())            StdOut.println(“Not in symmetric order”);

        if (!isSizeConsistent()) StdOut.println(“Subtree counts not consistent”);

        if (!isRankConsistent()) StdOut.println(“Ranks not consistent”);

        if (!is23())             StdOut.println(“Not a 2-3 tree”);

        if (!isBalanced())       StdOut.println(“Not balanced”);

        return isBST() && isSizeConsistent() && isRankConsistent() && is23() && isBalanced();

    }

    // does this binary tree satisfy symmetric order?    // Note: this test also ensures that data structure is a binary tree since order is strict    private boolean isBST() {

        return isBST(root, null, null);

    }

    // is the tree rooted at x a BST with all keys strictly between min and max    // (if min or max is null, treat as empty constraint)    // Credit: Bob Dondero’s elegant solution    private boolean isBST(Node x, Key min, Key max) {

        if (x == null) return true;

        if (min != null && x.key.compareTo(min) <= 0) return false;         if (max != null && x.key.compareTo(max) >= 0) return false;

        return isBST(x.left, min, x.key) && isBST(x.right, x.key, max);

    } 

    // are the size fields correct?    private boolean isSizeConsistent() { return isSizeConsistent(root); }

    private boolean isSizeConsistent(Node x) {

        if (x == null) return true;

        if (x.size != size(x.left) + size(x.right) + 1) return false;

        return isSizeConsistent(x.left) && isSizeConsistent(x.right);

    } 

    // check that ranks are consistent    private boolean isRankConsistent() {

        for (int i = 0; i < size(); i++)             if (i != rank(select(i))) return false;         for (Key key : keys())             if (key.compareTo(select(rank(key))) != 0) return false;         return true;     }     // Does the tree have no red right links, and at most one (left)    // red links in a row on any path?    private boolean is23() { return is23(root); }     private boolean is23(Node x) {         if (x == null) return true;         if (isRed(x.right)) return false;         if (x != root && isRed(x) && isRed(x.left))             return false;         return is23(x.left) && is23(x.right);     }      // do all paths from root to leaf have same number of black edges?    private boolean isBalanced() {         int black = 0;     // number of black links on path from root to min        Node x = root;         while (x != null) {             if (!isRed(x)) black++;             x = x.left;         }         return isBalanced(root, black);     }     // does every path from the root to a leaf have the given number of black links?    private boolean isBalanced(Node x, int black) {         if (x == null) return black == 0;         if (!isRed(x)) black--;         return isBalanced(x.left, black) && isBalanced(x.right, black);     }      /**     * Unit tests the {@code RedBlackBST} data type.     *     * @param args the command-line arguments     */     public static void main(String[] args) {         RedBlackBST st = new RedBlackBST();

        for (int i = 0; !StdIn.isEmpty(); i++) {

            String key = StdIn.readString();

            st.put(key, i);

        }

        StdOut.println();

        for (String s : st.keys())

            StdOut.println(s + ” ” + st.get(s));

        StdOut.println();

    }

}

/****************************************************************************** *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. * *  This file is part of algs4.jar, which accompanies the textbook * *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. *      http://algs4.cs.princeton.edu * * *  algs4.jar is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  algs4.jar is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with algs4.jar.  If not, see http://www.gnu.org/licenses. ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayBag.java
edu/princeton/cs/algs4/ResizingArrayBag.java
/******************************************************************************

 *  Compilation:  javac ResizingArrayBag.java

 *  Execution:    java ResizingArrayBag

 *  Dependencies: StdIn.java StdOut.java

 *  

 *  Bag implementation with a resizing array.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

import
 java
.
util
.
NoSuchElementException
;

/**

 *  The {
@code
 ResizingArrayBag} class represents a bag (or multiset) of 

 *  generic items. It supports insertion and iterating over the 

 *  items in arbitrary order.

 *  

 *  This implementation uses a resizing array.

 *  See {
@link
 LinkedBag} for a version that uses a singly linked list.

 *  The add operation takes constant amortized time; the

 *  isEmpty, and size operations

 *  take constant time. Iteration takes time proportional to the number of items.

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ResizingArrayBag
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Item
[]
 a
;
         
// array of items

    
private
 
int
 n
;
            
// number of elements on bag

    
/**

     * Initializes an empty bag.

     */

    
public
 
ResizingArrayBag
()
 
{

        a 
=
 
(
Item
[])
 
new
 
Object
[
2
];

        n 
=
 
0
;

    
}

    
/**

     * Is this bag empty?

     * 
@return
 true if this bag is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 n 
==
 
0
;

    
}

    
/**

     * Returns the number of items in this bag.

     * 
@return
 the number of items in this bag

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
// resize the underlying array holding the elements

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>=
 n
;

        
Item
[]
 temp 
=
 
(
Item
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             temp [ i ]   =  a [ i ];         a  =  temp ;      }      /**      * Adds the item to this bag.      *  @param  item the item to add to this bag      */      public   void  add ( Item  item )   {          if   ( n  ==  a . length )  resize ( 2 * a . length );      // double size of array if necessary         a [ n ++ ]   =  item ;                              // add item      }      /**      * Returns an iterator that iterates over the items in the bag in arbitrary order.      *  @return  an iterator that iterates over the items in the bag in arbitrary order      */      public   Iterator < Item >
 iterator
()
 
{

        
return
 
new
 
ArrayIterator
();

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ArrayIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
int
 i 
=
 
0
;

        
public
 
boolean
 hasNext
()
  
{
 
return
 i 
<  n ;                                 }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Item  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              return  a [ i ++ ];          }      }      /**      * Unit tests the { @code  ResizingArrayBag} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          ResizingArrayBag < String >
 bag 
=
 
new
 
ResizingArrayBag
< String >
();

        bag
.
add
(
“Hello”
);

        bag
.
add
(
“World”
);

        bag
.
add
(
“how”
);

        bag
.
add
(
“are”
);

        bag
.
add
(
“you”
);

        
for
 
(
String
 s 
:
 bag
)

            
StdOut
.
println
(
s
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayQueue.java
edu/princeton/cs/algs4/ResizingArrayQueue.java
/******************************************************************************

 *  Compilation:  javac ResizingArrayQueue.java

 *  Execution:    java ResizingArrayQueue < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt    *    *  Queue implementation with a resizing array.  *  *  % java ResizingArrayQueue < tobe.txt   *  to be or not to be (2 left on queue)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  ResizingArrayQueue} class represents a first-in-first-out (FIFO)  *  queue of generic items.  *  It supports the usual enqueue and dequeue

 *  operations, along with methods for peeking at the first item,

 *  testing if the queue is empty, and iterating through

 *  the items in FIFO order.

 *  

 *  This implementation uses a resizing array, which double the underlying array

 *  when it is full and halves the underlying array when it is one-quarter full.

 *  The enqueue and dequeue operations take constant amortized time.

 *  The sizepeek, and is-empty operations takes

 *  constant time in the worst case. 

 *  

 *  For additional documentation, see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ResizingArrayQueue
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Item
[]
 q
;
       
// queue elements

    
private
 
int
 n
;
          
// number of elements on queue

    
private
 
int
 first
;
      
// index of first element of queue

    
private
 
int
 last
;
       
// index of next available slot

    
/**

     * Initializes an empty queue.

     */

    
public
 
ResizingArrayQueue
()
 
{

        q 
=
 
(
Item
[])
 
new
 
Object
[
2
];

        n 
=
 
0
;

        first 
=
 
0
;

        last 
=
 
0
;

    
}

    
/**

     * Is this queue empty?

     * 
@return
 true if this queue is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 n 
==
 
0
;

    
}

    
/**

     * Returns the number of items in this queue.

     * 
@return
 the number of items in this queue

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
// resize the underlying array

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>=
 n
;

        
Item
[]
 temp 
=
 
(
Item
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             temp [ i ]   =  q [( first  +  i )   %  q . length ];          }         q  =  temp ;         first  =   0 ;         last   =  n ;      }      /**      * Adds the item to this queue.      *  @param  item the item to add      */      public   void  enqueue ( Item  item )   {          // double size of array if necessary and recopy to front of array          if   ( n  ==  q . length )  resize ( 2 * q . length );     // double size of array if necessary         q [ last ++ ]   =  item ;                          // add item          if   ( last  ==  q . length )  last  =   0 ;            // wrap-around         n ++ ;      }      /**      * Removes and returns the item on this queue that was least recently added.      *  @return  the item on this queue that was least recently added      *  @throws  java.util.NoSuchElementException if this queue is empty      */      public   Item  dequeue ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );          Item  item  =  q [ first ];         q [ first ]   =   null ;                              // to avoid loitering         n -- ;         first ++ ;          if   ( first  ==  q . length )  first  =   0 ;             // wrap-around          // shrink size of array if necessary          if   ( n  >
 
0
 
&&
 n 
==
 q
.
length
/
4
)
 resize
(
q
.
length
/
2
);
 

        
return
 item
;

    
}

    
/**

     * Returns the item least recently added to this queue.

     * 
@return
 the item least recently added to this queue

     * 
@throws
 java.util.NoSuchElementException if this queue is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Queue underflow”
);

        
return
 q
[
first
];

    
}

    
/**

     * Returns an iterator that iterates over the items in this queue in FIFO order.

     * 
@return
 an iterator that iterates over the items in this queue in FIFO order

     */

    
public
 
Iterator
< Item >
 iterator
()
 
{

        
return
 
new
 
ArrayIterator
();

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ArrayIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
int
 i 
=
 
0
;

        
public
 
boolean
 hasNext
()
  
{
 
return
 i 
<  n ;                                 }          public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }          public   Item  next ()   {              if   ( ! hasNext ())   throw   new   NoSuchElementException ();              Item  item  =  q [( i  +  first )   %  q . length ];             i ++ ;              return  item ;          }      }     /**      * Unit tests the { @code  ResizingArrayQueue} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          ResizingArrayQueue < String >
 queue 
=
 
new
 
ResizingArrayQueue
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))
 queue
.
enqueue
(
item
);

            
else
 
if
 
(
!
queue
.
isEmpty
())
 
StdOut
.
print
(
queue
.
dequeue
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 queue
.
size
()
 
+
 
” left on queue)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayStack.java
edu/princeton/cs/algs4/ResizingArrayStack.java
/******************************************************************************

 *  Compilation:  javac ResizingArrayStack.java

 *  Execution:    java ResizingArrayStack < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  *    *  Stack implementation with a resizing array.  *  *  % more tobe.txt   *  to be or not to - be - - that - - - is  *  *  % java ResizingArrayStack < tobe.txt  *  to be not that or be (2 left on stack)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  ResizingArrayStack} class represents a last-in-first-out (LIFO) stack  *  of generic items.  *  It supports the usual push and pop operations, along with methods

 *  for peeking at the top item, testing if the stack is empty, and iterating through

 *  the items in LIFO order.

 *  

 *  This implementation uses a resizing array, which double the underlying array

 *  when it is full and halves the underlying array when it is one-quarter full.

 *  The push and pop operations take constant amortized time.

 *  The sizepeek, and is-empty operations takes

 *  constant time in the worst case. 

 *  

 *  For additional documentation,

 *  see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ResizingArrayStack
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Item
[]
 a
;
         
// array of items

    
private
 
int
 n
;
            
// number of elements on stack

    
/**

     * Initializes an empty stack.

     */

    
public
 
ResizingArrayStack
()
 
{

        a 
=
 
(
Item
[])
 
new
 
Object
[
2
];

        n 
=
 
0
;

    
}

    
/**

     * Is this stack empty?

     * 
@return
 true if this stack is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 n 
==
 
0
;

    
}

    
/**

     * Returns the number of items in the stack.

     * 
@return
 the number of items in the stack

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
// resize the underlying array holding the elements

    
private
 
void
 resize
(
int
 capacity
)
 
{

        
assert
 capacity 
>=
 n
;

        
// textbook implementation

        
Item
[]
 temp 
=
 
(
Item
[])
 
new
 
Object
[
capacity
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             temp [ i ]   =  a [ i ];          }         a  =  temp ;         // alternative implementation         // a = java.util.Arrays.copyOf(a, capacity);      }      /**      * Adds the item to this stack.      *  @param  item the item to add      */      public   void  push ( Item  item )   {          if   ( n  ==  a . length )  resize ( 2 * a . length );      // double size of array if necessary         a [ n ++ ]   =  item ;                              // add item      }      /**      * Removes and returns the item most recently added to this stack.      *  @return  the item most recently added      *  @throws  java.util.NoSuchElementException if this stack is empty      */      public   Item  pop ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );          Item  item  =  a [ n - 1 ];         a [ n - 1 ]   =   null ;                                // to avoid loitering         n -- ;          // shrink size of array if necessary          if   ( n  >
 
0
 
&&
 n 
==
 a
.
length
/
4
)
 resize
(
a
.
length
/
2
);

        
return
 item
;

    
}

    
/**

     * Returns (but does not remove) the item most recently added to this stack.

     * 
@return
 the item most recently added to this stack

     * 
@throws
 java.util.NoSuchElementException if this stack is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Stack underflow”
);

        
return
 a
[
n

1
];

    
}

    
/**

     * Returns an iterator to this stack that iterates through the items in LIFO order.

     * 
@return
 an iterator to this stack that iterates through the items in LIFO order.

     */

    
public
 
Iterator
< Item >
 iterator
()
 
{

        
return
 
new
 
ReverseArrayIterator
();

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ReverseArrayIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
int
 i
;

        
public
 
ReverseArrayIterator
()
 
{

            i 
=
 n

1
;

        
}

        
public
 
boolean
 hasNext
()
 
{

            
return
 i 
>=
 
0
;

        
}

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
return
 a
[
i

];

        
}

    
}

    
/**

     * Unit tests the {
@code
 Stack} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
ResizingArrayStack
< String >
 stack 
=
 
new
 
ResizingArrayStack
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))
 stack
.
push
(
item
);

            
else
 
if
 
(
!
stack
.
isEmpty
())
 
StdOut
.
print
(
stack
.
pop
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 stack
.
size
()
 
+
 
” left on stack)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/RunLength.java
edu/princeton/cs/algs4/RunLength.java
/******************************************************************************

 *  Compilation:  javac RunLength.java

 *  Execution:    java RunLength – < input.txt   (compress)  *  Execution:    java RunLength + < input.txt   (expand)  *  Dependencies: BinaryIn.java BinaryOut.java  *  Data files:   https://algs4.cs.princeton.edu/55compression/4runs.bin  *                https://algs4.cs.princeton.edu/55compression/q32x48.bin  *                https://algs4.cs.princeton.edu/55compression/q64x96.bin  *  *  Compress or expand binary input from standard input using  *  run-length encoding.  *  *  % java BinaryDump 40 < 4runs.bin   *  0000000000000001111111000000011111111111  *  40 bits  *  *  This has runs of 15 0s, 7 1s, 7 0s, and 11 1s.  *  *  % java RunLength - < 4runs.bin | java HexDump  *  0f 07 07 0b  *  4 bytes  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  RunLength} class provides static methods for compressing  *  and expanding a binary input using run-length coding with 8-bit  *  run lengths.  *  

 *  For additional documentation,

 *  see Section 5.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
RunLength
 
{

    
private
 
static
 
final
 
int
 R    
=
 
256
;

    
private
 
static
 
final
 
int
 LG_R 
=
 
8
;

    
// Do not instantiate.

    
private
 
RunLength
()
 
{
 
}

    
/**

     * Reads a sequence of bits from standard input (that are encoded

     * using run-length encoding with 8-bit run lengths); decodes them;

     * and writes the results to standard output.

     */

    
public
 
static
 
void
 expand
()
 
{
 

        
boolean
 b 
=
 
false
;
 

        
while
 
(
!
BinaryStdIn
.
isEmpty
())
 
{

            
int
 run 
=
 
BinaryStdIn
.
readInt
(
LG_R
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  run ;  i ++ )                  BinaryStdOut . write ( b );             b  =   ! b ;          }          BinaryStdOut . close ();      }      /**      * Reads a sequence of bits from standard input; compresses      * them using run-length coding with 8-bit run lengths; and writes the      * results to standard output.      */      public   static   void  compress ()   {            char  run  =   0 ;            boolean  old  =   false ;          while   ( ! BinaryStdIn . isEmpty ())   {                boolean  b  =   BinaryStdIn . readBoolean ();              if   ( b  !=  old )   {                  BinaryStdOut . write ( run ,  LG_R );                 run  =   1 ;                 old  =   ! old ;              }              else   {                    if   ( run  ==  R - 1 )   {                        BinaryStdOut . write ( run ,  LG_R );                     run  =   0 ;                      BinaryStdOut . write ( run ,  LG_R );                  }                 run ++ ;              }            }            BinaryStdOut . write ( run ,  LG_R );          BinaryStdOut . close ();      }      /**      * Sample client that calls { @code  compress()} if the command-line      * argument is "-" an { @code  expand()} if it is "+".      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          if        ( args [ 0 ]. equals ( "-" ))  compress ();          else   if   ( args [ 0 ]. equals ( "+" ))  expand ();          else   throw   new   IllegalArgumentException ( "Illegal command line argument" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SegmentTree.java edu/princeton/cs/algs4/SegmentTree.java /******************************************************************************  *  Compilation:  javac SegmentTree.java  *  Execution:    java SegmentTree  *    *  A segment tree data structure.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  * The { @code  SegmentTree} class is an structure for efficient search of cummulative data.  * It performs  Range Minimum Query and Range Sum Query in O(log(n)) time.  * It can be easily customizable to support Range Max Query, Range Multiplication Query etc.  * 

 * Also it has been develop with  {
@code
 LazyPropagation} for range updates, which means

 * when you perform update operations over a range, the update process affects the least nodes as possible

 * so that the bigger the range you want to update the less time it consumes to update it. Eventually those changes will be propagated

 * to the children and the whole array will be up to date.

 * 

 * Example:

 * 

 * SegmentTreeHeap st = new SegmentTreeHeap(new Integer[]{1,3,4,2,1, -2, 4});

 * st.update(0,3, 1)

 * In the above case only the node that represents the range [0,3] will be updated (and not their children) so in this case

 * the update task will be less than n*log(n)

 *

 * Memory usage:  O(n)

 *

 * 
@author
 Ricardo Pacheco 

 */

public
 
class
 
SegmentTree
 
{

    
private
 
Node
[]
 heap
;

    
private
 
int
[]
 array
;

    
private
 
int
 size
;

    
/**

     * Time-Complexity:  O(n*log(n))

     *

     * 
@param
 array the Initialization array

     */

    
public
 
SegmentTree
(
int
[]
 array
)
 
{

        
this
.
array 
=
 
Arrays
.
copyOf
(
array
,
 array
.
length
);

        
//The max size of this array is about 2 * 2 ^ log2(n) + 1

        size 
=
 
(
int
)
 
(
2
 
*
 
Math
.
pow
(
2.0
,
 
Math
.
floor
((
Math
.
log
((
double
)
 array
.
length
)
 
/
 
Math
.
log
(
2.0
))
 
+
 
1
)));

        heap 
=
 
new
 
Node
[
size
];

        build
(
1
,
 
0
,
 array
.
length
);

    
}

    
public
 
int
 size
()
 
{

        
return
 array
.
length
;

    
}

    
//Initialize the Nodes of the Segment tree

    
private
 
void
 build
(
int
 v
,
 
int
 from
,
 
int
 size
)
 
{

        heap
[
v
]
 
=
 
new
 
Node
();

        heap
[
v
].
from 
=
 from
;

        heap
[
v
].
to 
=
 from 
+
 size 

 
1
;

        
if
 
(
size 
==
 
1
)
 
{

            heap
[
v
].
sum 
=
 array
[
from
];

            heap
[
v
].
min 
=
 array
[
from
];

        
}
 
else
 
{

            
//Build childs

            build
(
2
 
*
 v
,
 from
,
 size 
/
 
2
);

            build
(
2
 
*
 v 
+
 
1
,
 from 
+
 size 
/
 
2
,
 size 

 size 
/
 
2
);

            heap
[
v
].
sum 
=
 heap
[
2
 
*
 v
].
sum 
+
 heap
[
2
 
*
 v 
+
 
1
].
sum
;

            
//min = min of the children

            heap
[
v
].
min 
=
 
Math
.
min
(
heap
[
2
 
*
 v
].
min
,
 heap
[
2
 
*
 v 
+
 
1
].
min
);

        
}

    
}

    
/**

     * Range Sum Query

     *

     * Time-Complexity: O(log(n))

     *

     * 
@param
  from from index

     * 
@param
  to to index

     * 
@return
 sum

     */

    
public
 
int
 rsq
(
int
 from
,
 
int
 to
)
 
{

        
return
 rsq
(
1
,
 from
,
 to
);

    
}

    
private
 
int
 rsq
(
int
 v
,
 
int
 from
,
 
int
 to
)
 
{

        
Node
 n 
=
 heap
[
v
];

        
//If you did a range update that contained this node, you can infer the Sum without going down the tree

        
if
 
(
n
.
pendingVal 
!=
 
null
 
&&
 contains
(
n
.
from
,
 n
.
to
,
 from
,
 to
))
 
{

            
return
 
(
to 

 from 
+
 
1
)
 
*
 n
.
pendingVal
;

        
}

        
if
 
(
contains
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            
return
 heap
[
v
].
sum
;

        
}

        
if
 
(
intersects
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            propagate
(
v
);

            
int
 leftSum 
=
 rsq
(
2
 
*
 v
,
 from
,
 to
);

            
int
 rightSum 
=
 rsq
(
2
 
*
 v 
+
 
1
,
 from
,
 to
);

            
return
 leftSum 
+
 rightSum
;

        
}

        
return
 
0
;

    
}

    
/**

     * Range Min Query

     * 

     * Time-Complexity: O(log(n))

     *

     * 
@param
  from from index

     * 
@param
  to to index

     * 
@return
 min

     */

    
public
 
int
 rMinQ
(
int
 from
,
 
int
 to
)
 
{

        
return
 rMinQ
(
1
,
 from
,
 to
);

    
}

    
private
 
int
 rMinQ
(
int
 v
,
 
int
 from
,
 
int
 to
)
 
{

        
Node
 n 
=
 heap
[
v
];

        
//If you did a range update that contained this node, you can infer the Min value without going down the tree

        
if
 
(
n
.
pendingVal 
!=
 
null
 
&&
 contains
(
n
.
from
,
 n
.
to
,
 from
,
 to
))
 
{

            
return
 n
.
pendingVal
;

        
}

        
if
 
(
contains
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            
return
 heap
[
v
].
min
;

        
}

        
if
 
(
intersects
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            propagate
(
v
);

            
int
 leftMin 
=
 rMinQ
(
2
 
*
 v
,
 from
,
 to
);

            
int
 rightMin 
=
 rMinQ
(
2
 
*
 v 
+
 
1
,
 from
,
 to
);

            
return
 
Math
.
min
(
leftMin
,
 rightMin
);

        
}

        
return
 
Integer
.
MAX_VALUE
;

    
}

    
/**

     * Range Update Operation.

     * With this operation you can update either one position or a range of positions with a given number.

     * The update operations will update the less it can to update the whole range (Lazy Propagation).

     * The values will be propagated lazily from top to bottom of the segment tree.

     * This behavior is really useful for updates on portions of the array

     * 

     * Time-Complexity: O(log(n))

     *

     * 
@param
 from  from index

     * 
@param
 to    to index

     * 
@param
 value value

     */

    
public
 
void
 update
(
int
 from
,
 
int
 to
,
 
int
 value
)
 
{

        update
(
1
,
 from
,
 to
,
 value
);

    
}

    
private
 
void
 update
(
int
 v
,
 
int
 from
,
 
int
 to
,
 
int
 value
)
 
{

        
//The Node of the heap tree represents a range of the array with bounds: [n.from, n.to]

        
Node
 n 
=
 heap
[
v
];

        
/**

         * If the updating-range contains the portion of the current Node  We lazily update it.

         * This means We do NOT update each position of the vector, but update only some temporal

         * values into the Node; such values into the Node will be propagated down to its children only when they need to.

         */

        
if
 
(
contains
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            change
(
n
,
 value
);

        
}

        
if
 
(
n
.
size
()
 
==
 
1
)
 
return
;

        
if
 
(
intersects
(
from
,
 to
,
 n
.
from
,
 n
.
to
))
 
{

            
/**

             * Before keeping going down to the tree We need to propagate the

             * the values that have been temporally/lazily saved into this Node to its children

             * So that when We visit them the values  are properly updated

             */

            propagate
(
v
);

            update
(
2
 
*
 v
,
 from
,
 to
,
 value
);

            update
(
2
 
*
 v 
+
 
1
,
 from
,
 to
,
 value
);

            n
.
sum 
=
 heap
[
2
 
*
 v
].
sum 
+
 heap
[
2
 
*
 v 
+
 
1
].
sum
;

            n
.
min 
=
 
Math
.
min
(
heap
[
2
 
*
 v
].
min
,
 heap
[
2
 
*
 v 
+
 
1
].
min
);

        
}

    
}

    
//Propagate temporal values to children

    
private
 
void
 propagate
(
int
 v
)
 
{

        
Node
 n 
=
 heap
[
v
];

        
if
 
(
n
.
pendingVal 
!=
 
null
)
 
{

            change
(
heap
[
2
 
*
 v
],
 n
.
pendingVal
);

            change
(
heap
[
2
 
*
 v 
+
 
1
],
 n
.
pendingVal
);

            n
.
pendingVal 
=
 
null
;
 
//unset the pending propagation value

        
}

    
}

    
//Save the temporal values that will be propagated lazily

    
private
 
void
 change
(
Node
 n
,
 
int
 value
)
 
{

        n
.
pendingVal 
=
 value
;

        n
.
sum 
=
 n
.
size
()
 
*
 value
;

        n
.
min 
=
 value
;

        array
[
n
.
from
]
 
=
 value
;

    
}

    
//Test if the range1 contains range2

    
private
 
boolean
 contains
(
int
 from1
,
 
int
 to1
,
 
int
 from2
,
 
int
 to2
)
 
{

        
return
 from2 
>=
 from1 
&&
 to2 
<=  to1 ;      }      //check inclusive intersection, test if range1[from1, to1] intersects range2[from2, to2]      private   boolean  intersects ( int  from1 ,   int  to1 ,   int  from2 ,   int  to2 )   {          return  from1  <=  from2  &&  to1  >=
 from2   
//  (.[..)..] or (.[…]..)

                
||
 from1 
>=
 from2 
&&
 from1 
<=  to2 ;   // [.(..]..) or [..(..)..      }      //The Node class represents a partition range of the array.      static   class   Node   {          int  sum ;          int  min ;          //Here We store the value that will be propagated lazily          Integer  pendingVal  =   null ;          int  from ;          int  to ;          int  size ()   {              return  to  -  from  +   1 ;          }      }      /**      * Read the following commands:      * init n v     Initializes the array of size n with all v's      * set a b c... Initializes the array  with [a, b, c ...]      * rsq a b      Range Sum Query for the range [a, b]      * rmq a b      Range Min Query for the range [a, b]      * up  a b v    Update the [a,b] portion of the array with value v.      * exit      * 

     * Example:

     * init

     * set 1 2 3 4 5 6

     * rsq 1 3

     * Sum from 1 to 3 = 6

     * rmq 1 3

     * Min from 1 to 3 = 1

     * input up 1 3

     * [3,2,3,4,5,6]

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
SegmentTree
 st 
=
 
null
;

        
String
 cmd 
=
 
“cmp”
;

        
while
 
(
true
)
 
{

            
String
[]
 line 
=
 
StdIn
.
readLine
().
split
(
” ”
);

            
if
 
(
line
[
0
].
equals
(
“exit”
))
 
break
;

            
int
 arg1 
=
 
0
,
 arg2 
=
 
0
,
 arg3 
=
 
0
;

            
if
 
(
line
.
length 
>
 
1
)
 
{

                arg1 
=
 
Integer
.
parseInt
(
line
[
1
]);

            
}

            
if
 
(
line
.
length 
>
 
2
)
 
{

                arg2 
=
 
Integer
.
parseInt
(
line
[
2
]);

            
}

            
if
 
(
line
.
length 
>
 
3
)
 
{

                arg3 
=
 
Integer
.
parseInt
(
line
[
3
]);

            
}

            
if
 
((
!
line
[
0
].
equals
(
“set”
)
 
&&
 
!
line
[
0
].
equals
(
“init”
))
 
&&
 st 
==
 
null
)
 
{

                
StdOut
.
println
(
“Segment Tree not initialized”
);

                
continue
;

            
}

            
int
 array
[];

            
if
 
(
line
[
0
].
equals
(
“set”
))
 
{

                array 
=
 
new
 
int
[
line
.
length 

 
1
];

                
for
 
(
int
 i 
=
 
0
;
 i 
<  line . length  -   1 ;  i ++ )   {                     array [ i ]   =   Integer . parseInt ( line [ i  +   1 ]);                  }                 st  =   new   SegmentTree ( array );              }              else   if   ( line [ 0 ]. equals ( "init" ))   {                 array  =   new   int [ arg1 ];                  Arrays . fill ( array ,  arg2 );                 st  =   new   SegmentTree ( array );                  for   ( int  i  =   0 ;  i  <  st . size ();  i ++ )   {                      StdOut . print ( st . rsq ( i ,  i )   +   " " );                  }                  StdOut . println ();              }              else   if   ( line [ 0 ]. equals ( "up" ))   {                 st . update ( arg1 ,  arg2 ,  arg3 );                  for   ( int  i  =   0 ;  i  <  st . size ();  i ++ )   {                      StdOut . print ( st . rsq ( i ,  i )   +   " " );                  }                  StdOut . println ();              }              else   if   ( line [ 0 ]. equals ( "rsq" ))   {                  StdOut . printf ( "Sum from %d to %d = %d%n" ,  arg1 ,  arg2 ,  st . rsq ( arg1 ,  arg2 ));              }              else   if   ( line [ 0 ]. equals ( "rmq" ))   {                  StdOut . printf ( "Min from %d to %d = %d%n" ,  arg1 ,  arg2 ,  st . rMinQ ( arg1 ,  arg2 ));              }              else   {                  StdOut . println ( "Invalid command" );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Selection.java edu/princeton/cs/algs4/Selection.java /******************************************************************************  *  Compilation:  javac Selection.java  *  Execution:    java  Selection < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt  *                https://algs4.cs.princeton.edu/21elementary/words3.txt  *     *  Sorts a sequence of strings from standard input using selection sort.  *     *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Selection < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java Selection < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Comparator ; /**  *  The { @code  Selection} class provides static methods for sorting an  *  array using selection sort.

 *  This implementation makes ~ ½ n2 compares to sort

 *  any array of length n, so it is not suitable for sorting large arrays.

 *  It performs exactly n exchanges.

 *  

 *  This sorting algorithm is not stable. It uses Θ(1) extra memory

 *  (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.1

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Selection
 
{

    
// This class should not be instantiated.

    
private
 
Selection
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  min  =  i ;              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  if   ( less ( a [ j ],  a [ min ]))  min  =  j ;              }             exch ( a ,  i ,  min );              assert  isSorted ( a ,   0 ,  i );          }          assert  isSorted ( a );      }      /**      * Rearranges the array in ascending order, using a comparator.      *  @param  a the array      *  @param  comparator the comparator specifying the order      */      public   static   void  sort ( Object []  a ,   Comparator  comparator )   {          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  min  =  i ;              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  if   ( less ( comparator ,  a [ j ],  a [ min ]))  min  =  j ;              }             exch ( a ,  i ,  min );              assert  isSorted ( a ,  comparator ,   0 ,  i );          }          assert  isSorted ( a ,  comparator );      }     /***************************************************************************     *  Helper sorting functions.     ***************************************************************************/           // is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }      // is v < w ?      private   static   boolean  less ( Comparator  comparator ,   Object  v ,   Object  w )   {          return  comparator . compare ( v ,  w )   <   0 ;      }                        // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      // is the array a[] sorted?      private   static   boolean  isSorted ( Comparable []  a )   {          return  isSorted ( a ,   0 ,  a . length  -   1 );      }               // is the array sorted from a[lo] to a[hi]      private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // is the array a[] sorted?      private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {          return  isSorted ( a ,  comparator ,   0 ,  a . length  -   1 );      }      // is the array sorted from a[lo] to a[hi]      private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator ,   int  lo ,   int  hi )   {          for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )              if   ( less ( comparator ,  a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; selection sorts them;       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Selection . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SeparateChainingHashST.java edu/princeton/cs/algs4/SeparateChainingHashST.java /******************************************************************************  *  Compilation:  javac SeparateChainingHashST.java  *  Execution:    java SeparateChainingHashST < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/34hash/tinyST.txt  *  *  A symbol table implemented with a separate-chaining hash table.  *   ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  SeparateChainingHashST} class represents a symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This implementation uses a separate chaining hash table. It requires that

 *  the key type overrides the {
@code
 equals()} and {
@code
 hashCode()} methods.

 *  The expected time per putcontains, or remove

 *  operation is constant, subject to the uniform hashing assumption.

 *  The size, and is-empty operations take constant time.

 *  Construction takes constant time.

 *  

 *  For additional documentation, see Section 3.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  For other implementations, see {
@link
 ST}, {
@link
 BinarySearchST},

 *  {
@link
 SequentialSearchST}, {
@link
 BST}, {
@link
 RedBlackBST}, and

 *  {
@link
 LinearProbingHashST},

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
SeparateChainingHashST
< Key ,   Value >
 
{

    
private
 
static
 
final
 
int
 INIT_CAPACITY 
=
 
4
;

    
private
 
int
 n
;
                                
// number of key-value pairs

    
private
 
int
 m
;
                                
// hash table size

    
private
 
SequentialSearchST
< Key ,   Value >
[]
 st
;
  
// array of linked-list symbol tables

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
SeparateChainingHashST
()
 
{

        
this
(
INIT_CAPACITY
);

    
}
 

    
/**

     * Initializes an empty symbol table with {
@code
 m} chains.

     * 
@param
 m the initial number of chains

     */

    
public
 
SeparateChainingHashST
(
int
 m
)
 
{

        
this
.

=
 m
;

        st 
=
 
(
SequentialSearchST
< Key ,   Value >
[])
 
new
 
SequentialSearchST
[
m
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )             st [ i ]   =   new   SequentialSearchST < Key ,   Value >
();

    
}
 

    
// resize the hash table to have the given number of chains,

    
// rehashing all of the keys

    
private
 
void
 resize
(
int
 chains
)
 
{

        
SeparateChainingHashST
< Key ,   Value >
 temp 
=
 
new
 
SeparateChainingHashST
< Key ,   Value >
(
chains
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              for   ( Key  key  :  st [ i ]. keys ())   {                 temp . put ( key ,  st [ i ]. get ( key ));              }          }          this . m   =  temp . m ;          this . n   =  temp . n ;          this . st  =  temp . st ;      }      // hash value between 0 and m-1      private   int  hash ( Key  key )   {          return   ( key . hashCode ()   &   0x7fffffff )   %  m ;      }        /**      * Returns the number of key-value pairs in this symbol table.      *      *  @return  the number of key-value pairs in this symbol table      */      public   int  size ()   {          return  n ;      }        /**      * Returns true if this symbol table is empty.      *      *  @return  { @code  true} if this symbol table is empty;      *         { @code  false} otherwise      */      public   boolean  isEmpty ()   {          return  size ()   ==   0 ;      }      /**      * Returns true if this symbol table contains the specified key.      *      *  @param   key the key      *  @return  { @code  true} if this symbol table contains { @code  key};      *         { @code  false} otherwise      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   boolean  contains ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );          return  get ( key )   !=   null ;      }        /**      * Returns the value associated with the specified key in this symbol table.      *      *  @param   key the key      *  @return  the value associated with { @code  key} in the symbol table;      *         { @code  null} if no such value      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   Value  get ( Key  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );          int  i  =  hash ( key );          return  st [ i ]. get ( key );      }        /**      * Inserts the specified key-value pair into the symbol table, overwriting the old       * value with the new value if the symbol table already contains the specified key.      * Deletes the specified key (and its associated value) from this symbol table      * if the specified value is { @code  null}.      *      *  @param   key the key      *  @param   val the value      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  put ( Key  key ,   Value  val )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );          if   ( val  ==   null )   {             delete ( key );              return ;          }          // double table size if average length of list >= 10

        
if
 
(

>=
 
10
*
m
)
 resize
(
2
*
m
);

        
int
 i 
=
 hash
(
key
);

        
if
 
(
!
st
[
i
].
contains
(
key
))
 n
++
;

        st
[
i
].
put
(
key
,
 val
);

    
}
 

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).    

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to delete() is null”
);

        
int
 i 
=
 hash
(
key
);

        
if
 
(
st
[
i
].
contains
(
key
))
 n

;

        st
[
i
].
delete
(
key
);

        
// halve table size if average length of list <= 2          if   ( m  >
 INIT_CAPACITY 
&&
 n 
<=   2 * m )  resize ( m / 2 );      }        // return keys in symbol table as an Iterable      public   Iterable < Key >
 keys
()
 
{

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              for   ( Key  key  :  st [ i ]. keys ())                 queue . enqueue ( key );          }          return  queue ;      }        /**      * Unit tests the { @code  SeparateChainingHashST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {            SeparateChainingHashST < String ,   Integer >
 st 
=
 
new
 
SeparateChainingHashST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
// print keys

        
for
 
(
String
 s 
:
 st
.
keys
())
 

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));
 

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/SequentialSearchST.java
edu/princeton/cs/algs4/SequentialSearchST.java
/******************************************************************************

 *  Compilation:  javac SequentialSearchST.java

 *  Execution:    java SequentialSearchST

 *  Dependencies: StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyST.txt  

 *  

 *  Symbol table implementation with sequential search in an

 *  unordered linked list of key-value pairs.

 *

 *  % more tinyST.txt

 *  S E A R C H E X A M P L E

 *

 *  % java SequentialSearchST < tinyST.txt   *  L 11  *  P 10  *  M 9  *  X 7  *  H 5  *  C 4  *  R 3  *  A 8  *  E 12  *  S 0  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  SequentialSearchST} class represents an (unordered)  *  symbol table of generic key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  The class also uses the convention that values cannot be {
@code
 null}. Setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  It relies on the {
@code
 equals()} method to test whether two keys

 *  are equal. It does not call either the {
@code
 compareTo()} or

 *  {
@code
 hashCode()} method. 

 *  

 *  This implementation uses a singly linked list and

 *  sequential search.

 *  The put and delete operations take Θ(n).

 *  The get and contains operations takes Θ(n)

 *  time in the worst case.

 *  The size, and is-empty operations take Θ(1) time.

 *  Construction takes Θ(1) time.

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
SequentialSearchST
< Key ,   Value >
 
{

    
private
 
int
 n
;
           
// number of key-value pairs

    
private
 
Node
 first
;
      
// the linked list of key-value pairs

    
// a helper linked list data type

    
private
 
class
 
Node
 
{

        
private
 
Key
 key
;

        
private
 
Value
 val
;

        
private
 
Node
 next
;

        
public
 
Node
(
Key
 key
,
 
Value
 val
,
 
Node
 next
)
  
{

            
this
.
key  
=
 key
;

            
this
.
val  
=
 val
;

            
this
.
next 
=
 next
;

        
}

    
}

    
/**

     * Initializes an empty symbol table.

     */

    
public
 
SequentialSearchST
()
 
{

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     *

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns true if this symbol table is empty.

     *

     * 
@return
 {
@code
 true} if this symbol table is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns true if this symbol table contains the specified key.

     *

     * 
@param
  key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key};

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
/**

     * Returns the value associated with the given key in this symbol table.

     *

     * 
@param
  key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *     and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);
 

        
for
 
(
Node
 x 
=
 first
;
 x 
!=
 
null
;
 x 
=
 x
.
next
)
 
{

            
if
 
(
key
.
equals
(
x
.
key
))

                
return
 x
.
val
;

        
}

        
return
 
null
;

    
}

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting the old 

     * value with the new value if the symbol table already contains the specified key.

     * Deletes the specified key (and its associated value) from this symbol table

     * if the specified value is {
@code
 null}.

     *

     * 
@param
  key the key

     * 
@param
  val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to put() is null”
);
 

        
if
 
(
val 
==
 
null
)
 
{

            delete
(
key
);

            
return
;

        
}

        
for
 
(
Node
 x 
=
 first
;
 x 
!=
 
null
;
 x 
=
 x
.
next
)
 
{

            
if
 
(
key
.
equals
(
x
.
key
))
 
{

                x
.
val 
=
 val
;

                
return
;

            
}

        
}

        first 
=
 
new
 
Node
(
key
,
 val
,
 first
);

        n
++
;

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).    

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to delete() is null”
);
 

        first 
=
 delete
(
first
,
 key
);

    
}

    
// delete key in linked list beginning at Node x

    
// warning: function call stack too large if table is large

    
private
 
Node
 delete
(
Node
 x
,
 
Key
 key
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
if
 
(
key
.
equals
(
x
.
key
))
 
{

            n

;

            
return
 x
.
next
;

        
}

        x
.
next 
=
 delete
(
x
.
next
,
 key
);

        
return
 x
;

    
}

    
/**

     * Returns all keys in the symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     *

     * 
@return
 all keys in the symbol table

     */

    
public
 
Iterable
< Key >
 keys
()
  
{

        
Queue
< Key >
 queue 
=
 
new
 
Queue
< Key >
();

        
for
 
(
Node
 x 
=
 first
;
 x 
!=
 
null
;
 x 
=
 x
.
next
)

            queue
.
enqueue
(
x
.
key
);

        
return
 queue
;

    
}

    
/**

     * Unit tests the {
@code
 SequentialSearchST} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
SequentialSearchST
< String ,   Integer >
 st 
=
 
new
 
SequentialSearchST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
for
 
(
String
 s 
:
 st
.
keys
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/SET.java
edu/princeton/cs/algs4/SET.java
/******************************************************************************

 *  Compilation:  javac SET.java

 *  Execution:    java SET

 *  Dependencies: StdOut.java

 *  

 *  Set implementation using Java’s TreeSet library.

 *  Does not allow duplicates.

 *

 *  % java SET

 *  128.112.136.11

 *  208.216.181.15

 *  null

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Iterator
;

import
 java
.
util
.
NoSuchElementException
;

import
 java
.
util
.
TreeSet
;

/**

 *  The {
@code
 SET} class represents an ordered set of comparable keys.

 *  It supports the usual addcontains, and delete

 *  methods. It also provides ordered methods for finding the minimum,

 *  maximumfloor, and ceiling and set methods

 *  for unionintersection, and equality.

 *  

 *  Even though this implementation include the method {
@code
 equals()}, it

 *  does not support the method {
@code
 hashCode()} because sets are mutable.

 *  

 *  This implementation uses a balanced binary search tree. It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  The addcontainsdeleteminimum,

 *  maximumceiling, and floor methods take

 *  logarithmic time in the worst case.

 *  The size, and is-empty operations take constant time.

 *  Construction takes constant time.

 *  

 *  For additional documentation, see

 *  Section 3.5 of

 *  Algorithms in Java, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of a key in this set

 */

public
 
class
 SET
< Key   extends   Comparable < Key >>
 
implements
 
Iterable
< Key >
 
{

    
private
 
TreeSet
< Key >
 set
;

    
/**

     * Initializes an empty set.

     */

    
public
 SET
()
 
{

        set 
=
 
new
 
TreeSet
< Key >
();

    
}

    
/**

     * Initializes a new set that is an independent copy of the specified set.

     *

     * 
@param
 x the set to copy

     */

    
public
 SET
(
SET
< Key >
 x
)
 
{

        set 
=
 
new
 
TreeSet
< Key >
(
x
.
set
);

    
}

    
/**

     * Adds the key to this set (if it is not already present).

     *

     * 
@param
  key the key to add

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 add
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called add() with a null key”
);

        set
.
add
(
key
);

    
}

    
/**

     * Returns true if this set contains the given key.

     *

     * 
@param
  key the key

     * 
@return
 {
@code
 true} if this set contains {
@code
 key};

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called contains() with a null key”
);

        
return
 set
.
contains
(
key
);

    
}

    
/**

     * Removes the specified key from this set (if the set contains the specified key).

     * This is equivalent to {
@code
 remove()}, but we plan to deprecate {
@code
 delete()}.

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called delete() with a null key”
);

        set
.
remove
(
key
);

    
}

    
/**

     * Removes the specified key from this set (if the set contains the specified key).

     * This is equivalent to {
@code
 delete()}, but we plan to deprecate {
@code
 delete()}.

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 remove
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called remove() with a null key”
);

        set
.
remove
(
key
);

    
}

    
/**

     * Returns the number of keys in this set.

     *

     * 
@return
 the number of keys in this set

     */

    
public
 
int
 size
()
 
{

        
return
 set
.
size
();

    
}

    
/**

     * Returns true if this set is empty.

     *

     * 
@return
 {
@code
 true} if this set is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

 

    
/**

     * Returns all of the keys in this set, as an iterator.

     * To iterate over all of the keys in a set named {
@code
 set}, use the

     * foreach notation: {
@code
 for (Key key : set)}.

     *

     * 
@return
 an iterator to all of the keys in this set

     */

    
public
 
Iterator
< Key >
 iterator
()
 
{

        
return
 set
.
iterator
();

    
}

    
/**

     * Returns the largest key in this set.

     *

     * 
@return
 the largest key in this set

     * 
@throws
 NoSuchElementException if this set is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called max() with empty set”
);

        
return
 set
.
last
();

    
}

    
/**

     * Returns the smallest key in this set.

     *

     * 
@return
 the smallest key in this set

     * 
@throws
 NoSuchElementException if this set is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“called min() with empty set”
);

        
return
 set
.
first
();

    
}

    
/**

     * Returns the smallest key in this set greater than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the smallest key in this set greater than or equal to {
@code
 key}

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     * 
@throws
 NoSuchElementException if there is no such key

     */

    
public
 
Key
 ceiling
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called ceiling() with a null key”
);

        
Key
 k 
=
 set
.
ceiling
(
key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“all keys are less than ”
 
+
 key
);

        
return
 k
;

    
}

    
/**

     * Returns the largest key in this set less than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the largest key in this set table less than or equal to {
@code
 key}

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     * 
@throws
 NoSuchElementException if there is no such key

     */

    
public
 
Key
 floor
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called floor() with a null key”
);

        
Key
 k 
=
 set
.
floor
(
key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“all keys are greater than ”
 
+
 key
);

        
return
 k
;

    
}

    
/**

     * Returns the union of this set and that set.

     *

     * 
@param
  that the other set

     * 
@return
 the union of this set and that set

     * 
@throws
 IllegalArgumentException if {
@code
 that} is {
@code
 null}

     */

    
public
 SET
< Key >
 union
(
SET
< Key >
 that
)
 
{

        
if
 
(
that 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called union() with a null argument”
);

        SET
< Key >
 c 
=
 
new
 SET
< Key >
();

        
for
 
(
Key
 x 
:
 
this
)
 
{

            c
.
add
(
x
);

        
}

        
for
 
(
Key
 x 
:
 that
)
 
{

            c
.
add
(
x
);

        
}

        
return
 c
;

    
}

    
/**

     * Returns the intersection of this set and that set.

     *

     * 
@param
  that the other set

     * 
@return
 the intersection of this set and that set

     * 
@throws
 IllegalArgumentException if {
@code
 that} is {
@code
 null}

     */

    
public
 SET
< Key >
 intersects
(
SET
< Key >
 that
)
 
{

        
if
 
(
that 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“called intersects() with a null argument”
);

        SET
< Key >
 c 
=
 
new
 SET
< Key >
();

        
if
 
(
this
.
size
()
 
<  that . size ())   {              for   ( Key  x  :   this )   {                  if   ( that . contains ( x ))  c . add ( x );              }          }          else   {              for   ( Key  x  :  that )   {                  if   ( this . contains ( x ))  c . add ( x );              }          }          return  c ;      }      /**             * Compares this set to the specified set.      * 

     * Note that this method declares two empty sets to be equal

     * even if they are parameterized by different generic types.

     * This is consistent with the behavior of {
@code
 equals()} 

     * within Java’s Collections framework.

     *       

     * 
@param
  other the other set

     * 
@return
 {
@code
 true} if this set equals {
@code
 other};

     *         {
@code
 false} otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        SET that 
=
 
(
SET
)
 other
;

        
return
 
this
.
set
.
equals
(
that
.
set
);

    
}

    
/**

     * This operation is not supported because sets are mutable.

     *

     * 
@return
 does not return a value

     * 
@throws
 UnsupportedOperationException if called

     */

    @
Override

    
public
 
int
 hashCode
()
 
{

        
throw
 
new
 
UnsupportedOperationException
(
“hashCode() is not supported because sets are mutable”
);

    
}

    
/**

     * Returns a string representation of this set.

     *

     * 
@return
 a string representation of this set, enclosed in curly braces,

     *         with adjacent keys separated by a comma and a space

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
String
 s 
=
 set
.
toString
();

        
return
 
“{ ”
 
+
 s
.
substring
(
1
,
 s
.
length
()
 

 
1
)
 
+
 
” }”
;

    
}

    
/**

     * Unit tests the {
@code
 SET} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        SET
< String >
 set 
=
 
new
 SET
< String >
();

        
StdOut
.
println
(
“set = ”
 
+
 set
);

        
// insert some keys

        set
.
add
(
“www.cs.princeton.edu”
);

        set
.
add
(
“www.cs.princeton.edu”
);
    
// overwrite old value

        set
.
add
(
“www.princeton.edu”
);

        set
.
add
(
“www.math.princeton.edu”
);

        set
.
add
(
“www.yale.edu”
);

        set
.
add
(
“www.amazon.com”
);

        set
.
add
(
“www.simpsons.com”
);

        set
.
add
(
“www.stanford.edu”
);

        set
.
add
(
“www.google.com”
);

        set
.
add
(
“www.ibm.com”
);

        set
.
add
(
“www.apple.com”
);

        set
.
add
(
“www.slashdot.com”
);

        set
.
add
(
“www.whitehouse.gov”
);

        set
.
add
(
“www.espn.com”
);

        set
.
add
(
“www.snopes.com”
);

        set
.
add
(
“www.movies.com”
);

        set
.
add
(
“www.cnn.com”
);

        set
.
add
(
“www.iitb.ac.in”
);

        
StdOut
.
println
(
set
.
contains
(
“www.cs.princeton.edu”
));

        
StdOut
.
println
(
!
set
.
contains
(
“www.harvardsucks.com”
));

        
StdOut
.
println
(
set
.
contains
(
“www.simpsons.com”
));

        
StdOut
.
println
();

        
StdOut
.
println
(
“ceiling(www.simpsonr.com) = ”
 
+
 set
.
ceiling
(
“www.simpsonr.com”
));

        
StdOut
.
println
(
“ceiling(www.simpsons.com) = ”
 
+
 set
.
ceiling
(
“www.simpsons.com”
));

        
StdOut
.
println
(
“ceiling(www.simpsont.com) = ”
 
+
 set
.
ceiling
(
“www.simpsont.com”
));

        
StdOut
.
println
(
“floor(www.simpsonr.com)   = ”
 
+
 set
.
floor
(
“www.simpsonr.com”
));

        
StdOut
.
println
(
“floor(www.simpsons.com)   = ”
 
+
 set
.
floor
(
“www.simpsons.com”
));

        
StdOut
.
println
(
“floor(www.simpsont.com)   = ”
 
+
 set
.
floor
(
“www.simpsont.com”
));

        
StdOut
.
println
();

        
StdOut
.
println
(
“set = ”
 
+
 set
);

        
StdOut
.
println
();

        
// print out all keys in this set in lexicographic order

        
for
 
(
String
 s 
:
 set
)
 
{

            
StdOut
.
println
(
s
);

        
}

        
StdOut
.
println
();

        SET
< String >
 set2 
=
 
new
 SET
< String >
(
set
);

        
StdOut
.
println
(
set
.
equals
(
set2
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Shell.java
edu/princeton/cs/algs4/Shell.java
/******************************************************************************

 *  Compilation:  javac Shell.java

 *  Execution:    java Shell < input.txt  *  Dependencies: StdOut.java StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt  *                https://algs4.cs.princeton.edu/21elementary/words3.txt  *     *  Sorts a sequence of strings from standard input using shellsort.  *  *  % more tiny.txt  *  S O R T E X A M P L E  *  *  % java Shell < tiny.txt  *  A E E L M O P R S T X                 [ one string per line ]  *      *  % more words3.txt  *  bed bug dad yes zoo ... all bad yet  *    *  % java Shell < words3.txt  *  all bad bed bug dad ... yes yet zoo    [ one string per line ]  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Shell} class provides static methods for sorting an  *  array using Shellsort with

 *   Knuth’s increment sequence

 *  (1, 4, 13, 40, …). In the worst case, this implementation makes

 *  Θ(n3/2) compares and exchanges to sort

 *  an array of length n.

 *  

 *  This sorting algorithm is not stable.

 *  It uses Θ(1) extra memory (not including the input array).

 *  

 *  For additional documentation, see

 *  Section 2.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *  

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Shell
 
{

    
// This class should not be instantiated.

    
private
 
Shell
()
 
{
 
}

    
/**

     * Rearranges the array in ascending order, using the natural order.

     * 
@param
 a the array to be sorted

     */

    
public
 
static
 
void
 sort
(
Comparable
[]
 a
)
 
{

        
int
 n 
=
 a
.
length
;

        
// 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, … 

        
int
 h 
=
 
1
;

        
while
 
(

<  n / 3 )  h  =   3 * h  +   1 ;            while   ( h  >=
 
1
)
 
{

            
// h-sort the array

            
for
 
(
int
 i 
=
 h
;
 i 
<  n ;  i ++ )   {                  for   ( int  j  =  i ;  j  >=
 h 
&&
 less
(
a
[
j
],
 a
[
j

h
]);
 j 
-=
 h
)
 
{

                    exch
(
a
,
 j
,
 j

h
);

                
}

            
}

            
assert
 isHsorted
(
a
,
 h
);
 

            h 
/=
 
3
;

        
}

        
assert
 isSorted
(
a
);

    
}

   
/***************************************************************************

    *  Helper sorting functions.

    ***************************************************************************/

    

    
// is v < w ?      private   static   boolean  less ( Comparable  v ,   Comparable  w )   {          return  v . compareTo ( w )   <   0 ;      }               // exchange a[i] and a[j]      private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {          Object  swap  =  a [ i ];         a [ i ]   =  a [ j ];         a [ j ]   =  swap ;      }     /***************************************************************************     *  Check if array is sorted - useful for debugging.     ***************************************************************************/      private   static   boolean  isSorted ( Comparable []  a )   {          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;          return   true ;      }      // is the array h-sorted?      private   static   boolean  isHsorted ( Comparable []  a ,   int  h )   {          for   ( int  i  =  h ;  i  <  a . length ;  i ++ )              if   ( less ( a [ i ],  a [ i - h ]))   return   false ;          return   true ;      }      // print array to standard output      private   static   void  show ( Comparable []  a )   {          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              StdOut . println ( a [ i ]);          }      }      /**      * Reads in a sequence of strings from standard input; Shellsorts them;       * and prints them to standard output in ascending order.       *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String []  a  =   StdIn . readAllStrings ();          Shell . sort ( a );         show ( a );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SparseVector.java edu/princeton/cs/algs4/SparseVector.java /******************************************************************************  *  Compilation:  javac SparseVector.java  *  Execution:    java SparseVector  *  Dependencies: StdOut.java  *    *  A sparse vector, implementing using a symbol table.  *  *  [Not clear we need the instance variable N except for error checking.]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  SparseVector} class represents a d-dimensional mathematical vector.

 *  Vectors are mutable: their values can be changed after they are created.

 *  It includes methods for addition, subtraction,

 *  dot product, scalar product, unit vector, and Euclidean norm.

 *  

 *  The implementation is a symbol table of indices and values for which the vector

 *  coordinates are nonzero. This makes it efficient when most of the vector coordindates

  * are zero.

 *  

 *  For additional documentation,    

 *  see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *  See also {
@link
 Vector} for an immutable (dense) vector data type.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
SparseVector
 
{

    
private
 
int
 d
;
                   
// dimension

    
private
 ST
< Integer ,   Double >
 st
;
  
// the vector, represented by index-value pairs

   
/**

     * Initializes a d-dimensional zero vector.

     * 
@param
 d the dimension of the vector

     */

    
public
 
SparseVector
(
int
 d
)
 
{

        
this
.
d  
=
 d
;

        
this
.
st 
=
 
new
 ST
< Integer ,   Double >
();

    
}

   
/**

     * Sets the ith coordinate of this vector to the specified value.

     *

     * 
@param
  i the index

     * 
@param
  value the new value

     * 
@throws
 IllegalArgumentException unless i is between 0 and d-1

     */

    
public
 
void
 put
(
int
 i
,
 
double
 value
)
 
{

        
if
 
(

<   0   ||  i  >=
 d
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal index”
);

        
if
 
(
value 
==
 
0.0
)
 st
.
delete
(
i
);

        
else
              st
.
put
(
i
,
 value
);

    
}

   
/**

     * Returns the ith coordinate of this vector.

     *

     * 
@param
  i the index

     * 
@return
 the value of the ith coordinate of this vector

     * 
@throws
 IllegalArgumentException unless i is between 0 and d-1

     */

    
public
 
double
 get
(
int
 i
)
 
{

        
if
 
(

<   0   ||  i  >=
 d
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal index”
);

        
if
 
(
st
.
contains
(
i
))
 
return
 st
.
get
(
i
);

        
else
                
return
 
0.0
;

    
}

   
/**

     * Returns the number of nonzero entries in this vector.

     *

     * 
@return
 the number of nonzero entries in this vector

     */

    
public
 
int
 nnz
()
 
{

        
return
 st
.
size
();

    
}

   
/**

     * Returns the dimension of this vector.

     *

     * 
@return
 the dimension of this vector

     * 
@deprecated
 Replaced by {
@link
 #dimension()}.

     */

    @
Deprecated

    
public
 
int
 size
()
 
{

        
return
 d
;

    
}

   
/**

     * Returns the dimension of this vector.

     *

     * 
@return
 the dimension of this vector

     */

    
public
 
int
 dimension
()
 
{

        
return
 d
;

    
}

    
/**

     * Returns the inner product of this vector with the specified vector.

     *

     * 
@param
  that the other vector

     * 
@return
 the dot product between this vector and that vector

     * 
@throws
 IllegalArgumentException if the lengths of the two vectors are not equal

     */

    
public
 
double
 dot
(
SparseVector
 that
)
 
{

        
if
 
(
this
.

!=
 that
.
d
)
 
throw
 
new
 
IllegalArgumentException
(
“Vector lengths disagree”
);

        
double
 sum 
=
 
0.0
;

        
// iterate over the vector with the fewest nonzeros

        
if
 
(
this
.
st
.
size
()
 
<=  that . st . size ())   {              for   ( int  i  :   this . st . keys ())                  if   ( that . st . contains ( i ))  sum  +=   this . get ( i )   *  that . get ( i );          }          else    {              for   ( int  i  :  that . st . keys ())                  if   ( this . st . contains ( i ))  sum  +=   this . get ( i )   *  that . get ( i );          }          return  sum ;      }      /**      * Returns the inner product of this vector with the specified array.      *      *  @param   that the array      *  @return  the dot product between this vector and that array      *  @throws  IllegalArgumentException if the dimensions of the vector and the array are not equal      */      public   double  dot ( double []  that )   {          double  sum  =   0.0 ;          for   ( int  i  :  st . keys ())             sum  +=  that [ i ]   *   this . get ( i );          return  sum ;      }      /**      * Returns the magnitude of this vector.      * This is also known as the L2 norm or the Euclidean norm.      *       *  @return  the magnitude of this vector      */      public   double  magnitude ()   {          return   Math . sqrt ( this . dot ( this ));      }      /**      * Returns the Euclidean norm of this vector.      *      *  @return  the Euclidean norm of this vector      *  @deprecated  Replaced by { @link  #magnitude()}.      */     @ Deprecated      public   double  norm ()   {          return   Math . sqrt ( this . dot ( this ));      }      /**      * Returns the scalar-vector product of this vector with the specified scalar.      *      *  @param   alpha the scalar      *  @return  the scalar-vector product of this vector with the specified scalar      */      public   SparseVector  scale ( double  alpha )   {          SparseVector  c  =   new   SparseVector ( d );          for   ( int  i  :   this . st . keys ())  c . put ( i ,  alpha  *   this . get ( i ));          return  c ;      }      /**      * Returns the sum of this vector and the specified vector.      *      *  @param   that the vector to add to this vector      *  @return  the sum of this vector and that vector      *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal      */      public   SparseVector  plus ( SparseVector  that )   {          if   ( this . d  !=  that . d )   throw   new   IllegalArgumentException ( "Vector lengths disagree" );          SparseVector  c  =   new   SparseVector ( d );          for   ( int  i  :   this . st . keys ())  c . put ( i ,   this . get ( i ));                  // c = this          for   ( int  i  :  that . st . keys ())  c . put ( i ,  that . get ( i )   +  c . get ( i ));       // c = c + that          return  c ;      }     /**      * Returns a string representation of this vector.      *  @return  a string representation of this vector, which consists of the       *         the vector entries, separates by commas, enclosed in parentheses      */      public   String  toString ()   {          StringBuilder  s  =   new   StringBuilder ();          for   ( int  i  :  st . keys ())   {             s . append ( "("   +  i  +   ", "   +  st . get ( i )   +   ") " );          }          return  s . toString ();      }      /**      * Unit tests the { @code  SparseVector} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          SparseVector  a  =   new   SparseVector ( 10 );          SparseVector  b  =   new   SparseVector ( 10 );         a . put ( 3 ,   0.50 );         a . put ( 9 ,   0.75 );         a . put ( 6 ,   0.11 );         a . put ( 6 ,   0.00 );         b . put ( 3 ,   0.60 );         b . put ( 4 ,   0.90 );          StdOut . println ( "a = "   +  a );          StdOut . println ( "b = "   +  b );          StdOut . println ( "a dot b = "   +  a . dot ( b ));          StdOut . println ( "a + b   = "   +  a . plus ( b ));      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Stack.java edu/princeton/cs/algs4/Stack.java /******************************************************************************  *  Compilation:  javac Stack.java  *  Execution:    java Stack < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  *  *  A generic stack, implemented using a singly linked list.  *  Each stack element is of type Item.  *  *  This version uses a static nested class Node (to save 8 bytes per  *  Node), whereas the version in the textbook uses a non-static nested  *  class (for simplicity).  *    *  % more tobe.txt   *  to be or not to - be - - that - - - is  *  *  % java Stack < tobe.txt  *  to be not that or be (2 left on stack)  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; /**  *  The { @code  Stack} class represents a last-in-first-out (LIFO) stack of generic items.  *  It supports the usual push and pop operations, along with methods

 *  for peeking at the top item, testing if the stack is empty, and iterating through

 *  the items in LIFO order.

 *  

 *  This implementation uses a singly linked list with a static nested class for

 *  linked-list nodes. See {
@link
 LinkedStack} for the version from the

 *  textbook that uses a non-static nested class.

 *  See {
@link
 ResizingArrayStack} for a version that uses a resizing array.

 *  The pushpoppeeksize, and is-empty

 *  operations all take constant time in the worst case.

 *  

 *  For additional documentation,

 *  see Section 1.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of an item in this stack

 */

public
 
class
 
Stack
< Item >
 
implements
 
Iterable
< Item >
 
{

    
private
 
Node
< Item >
 first
;
     
// top of stack

    
private
 
int
 n
;
                
// size of the stack

    
// helper linked list class

    
private
 
static
 
class
 
Node
< Item >
 
{

        
private
 
Item
 item
;

        
private
 
Node
< Item >
 next
;

    
}

    
/**

     * Initializes an empty stack.

     */

    
public
 
Stack
()
 
{

        first 
=
 
null
;

        n 
=
 
0
;

    
}

    
/**

     * Returns true if this stack is empty.

     *

     * 
@return
 true if this stack is empty; false otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 first 
==
 
null
;

    
}

    
/**

     * Returns the number of items in this stack.

     *

     * 
@return
 the number of items in this stack

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Adds the item to this stack.

     *

     * 
@param
  item the item to add

     */

    
public
 
void
 push
(
Item
 item
)
 
{

        
Node
< Item >
 oldfirst 
=
 first
;

        first 
=
 
new
 
Node
< Item >
();

        first
.
item 
=
 item
;

        first
.
next 
=
 oldfirst
;

        n
++
;

    
}

    
/**

     * Removes and returns the item most recently added to this stack.

     *

     * 
@return
 the item most recently added

     * 
@throws
 NoSuchElementException if this stack is empty

     */

    
public
 
Item
 pop
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Stack underflow”
);

        
Item
 item 
=
 first
.
item
;
        
// save item to return

        first 
=
 first
.
next
;
            
// delete first node

        n

;

        
return
 item
;
                   
// return the saved item

    
}

    
/**

     * Returns (but does not remove) the item most recently added to this stack.

     *

     * 
@return
 the item most recently added to this stack

     * 
@throws
 NoSuchElementException if this stack is empty

     */

    
public
 
Item
 peek
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Stack underflow”
);

        
return
 first
.
item
;

    
}

    
/**

     * Returns a string representation of this stack.

     *

     * 
@return
 the sequence of items in this stack in LIFO order, separated by spaces

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 s 
=
 
new
 
StringBuilder
();

        
for
 
(
Item
 item 
:
 
this
)
 
{

            s
.
append
(
item
);

            s
.
append
(
‘ ‘
);

        
}

        
return
 s
.
toString
();

    
}

       

    
/**

     * Returns an iterator to this stack that iterates through the items in LIFO order.

     *

     * 
@return
 an iterator to this stack that iterates through the items in LIFO order

     */

    
public
 
Iterator
< Item >
 iterator
()
 
{

        
return
 
new
 
ListIterator
(
first
);

    
}

    
// an iterator, doesn’t implement remove() since it’s optional

    
private
 
class
 
ListIterator
 
implements
 
Iterator
< Item >
 
{

        
private
 
Node
< Item >
 current
;

        
public
 
ListIterator
(
Node
< Item >
 first
)
 
{

            current 
=
 first
;

        
}

        
public
 
boolean
 hasNext
()
 
{

            
return
 current 
!=
 
null
;

        
}

        
public
 
void
 remove
()
 
{

            
throw
 
new
 
UnsupportedOperationException
();

        
}

        
public
 
Item
 next
()
 
{

            
if
 
(
!
hasNext
())
 
throw
 
new
 
NoSuchElementException
();

            
Item
 item 
=
 current
.
item
;

            current 
=
 current
.
next
;
 

            
return
 item
;

        
}

    
}

    
/**

     * Unit tests the {
@code
 Stack} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Stack
< String >
 stack 
=
 
new
 
Stack
< String >
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 item 
=
 
StdIn
.
readString
();

            
if
 
(
!
item
.
equals
(
“-”
))

                stack
.
push
(
item
);

            
else
 
if
 
(
!
stack
.
isEmpty
())

                
StdOut
.
print
(
stack
.
pop
()
 
+
 
” ”
);

        
}

        
StdOut
.
println
(
“(”
 
+
 stack
.
size
()
 
+
 
” left on stack)”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/StaticSETofInts.java
edu/princeton/cs/algs4/StaticSETofInts.java
/******************************************************************************

 *  Compilation:  javac StaticSetOfInts.java

 *  Execution:    none

 *  Dependencies: StdOut.java

 *  

 *  Data type to store a set of integers.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Arrays
;

/**

 *  The {
@code
 StaticSETofInts} class represents a set of integers.

 *  It supports searching for a given integer is in the set. It accomplishes

 *  this by keeping the set of integers in a sorted array and using

 *  binary search to find the given integer.

 *  

 *  The rank and contains operations take

 *  logarithmic time in the worst case.

 *  

 *  For additional documentation, see Section 1.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
StaticSETofInts
 
{

    
private
 
int
[]
 a
;

    
/**

     * Initializes a set of integers specified by the integer array.

     * 
@param
 keys the array of integers

     * 
@throws
 IllegalArgumentException if the array contains duplicate integers

     */

    
public
 
StaticSETofInts
(
int
[]
 keys
)
 
{

        
// defensive copy

        a 
=
 
new
 
int
[
keys
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  keys . length ;  i ++ )             a [ i ]   =  keys [ i ];          // sort the integers          Arrays . sort ( a );          // check for duplicates          for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )              if   ( a [ i ]   ==  a [ i - 1 ])                  throw   new   IllegalArgumentException ( "Argument arrays contains duplicate keys." );      }      /**      * Is the key in this set of integers?      *  @param  key the search key      *  @return  true if the set of integers contains the key; false otherwise      */      public   boolean  contains ( int  key )   {          return  rank ( key )   !=   - 1 ;      }      /**      * Returns either the index of the search key in the sorted array      * (if the key is in the set) or -1 (if the key is not in the set).      *  @param  key the search key      *  @return  the number of keys in this set less than the key (if the key is in the set)      * or -1 (if the key is not in the set).      */      public   int  rank ( int  key )   {          int  lo  =   0 ;          int  hi  =  a . length  -   1 ;          while   ( lo  <=  hi )   {              // Key is in a[lo..hi] or not present.              int  mid  =  lo  +   ( hi  -  lo )   /   2 ;              if        ( key  <  a [ mid ])  hi  =  mid  -   1 ;              else   if   ( key  >
 a
[
mid
])
 lo 
=
 mid 
+
 
1
;

            
else
 
return
 mid
;

        
}

        
return
 

1
;

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/StdArrayIO.java
edu/princeton/cs/algs4/StdArrayIO.java
/******************************************************************************

 *  Compilation:  javac StdArrayIO.java

 *  Execution:    java StdArrayIO < input.txt  *  Dependencies: StdOut.java  *  Data files:    https://introcs.cs.princeton.edu/java/22library/tinyDouble1D.txt  *                 https://introcs.cs.princeton.edu/java/22library/tinyDouble2D.txt  *                 https://introcs.cs.princeton.edu/java/22library/tinyBoolean2D.txt  *  *  A library for reading in 1D and 2D arrays of integers, doubles,  *  and booleans from standard input and printing them out to  *  standard output.  *  *  % more tinyDouble1D.txt   *  4  *    .000  .246  .222  -.032  *  *  % more tinyDouble2D.txt   *  4 3   *    .000  .270  .000   *    .246  .224 -.036   *    .222  .176  .0893   *   -.032  .739  .270   *  *  % more tinyBoolean2D.txt   *  4 3   *    1 1 0  *    0 0 0  *    0 1 1  *    1 1 1  *  *  % cat tinyDouble1D.txt tinyDouble2D.txt tinyBoolean2D.txt | java StdArrayIO  *  4  *    0.00000   0.24600   0.22200  -0.03200   *    *  4 3  *    0.00000   0.27000   0.00000   *    0.24600   0.22400  -0.03600   *    0.22200   0.17600   0.08930   *    0.03200   0.73900   0.27000   *  *  4 3  *  1 1 0   *  0 0 0   *  0 1 1   *  1 1 1   *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  Standard array IO. This class provides methods for reading

 *  in 1D and 2D arrays from standard input and printing out to 

 *  standard output.

 *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
StdArrayIO
 
{

    
// it doesn’t make sense to instantiate this class

    
private
 
StdArrayIO
()
 
{
 
}

    
/**

     * Reads a 1D array of doubles from standard input and returns it.

     *

     * 
@return
 the 1D array of doubles

     */

    
public
 
static
 
double
[]
 readDouble1D
()
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        
double
[]
 a 
=
 
new
 
double
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             a [ i ]   =   StdIn . readDouble ();          }          return  a ;      }      /**      * Prints an array of doubles to standard output.      *      *  @param  a the 1D array of doubles      */      public   static   void  print ( double []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . printf ( "%9.5f " ,  a [ i ]);          }          StdOut . println ();      }               /**      * Reads a 2D array of doubles from standard input and returns it.      *      *  @return  the 2D array of doubles      */      public   static   double [][]  readDouble2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          double [][]  a  =   new   double [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readDouble ();              }          }          return  a ;      }      /**      * Prints the 2D array of doubles to standard output.      *      *  @param  a the 2D array of doubles      */      public   static   void  print ( double [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  StdOut . printf ( "%9.5f " ,  a [ i ][ j ]);              }              StdOut . println ();          }      }      /**      * Reads a 1D array of integers from standard input and returns it.      *      *  @return  the 1D array of integers      */      public   static   int []  readInt1D ()   {          int  n  =   StdIn . readInt ();          int []  a  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             a [ i ]   =   StdIn . readInt ();          }          return  a ;      }      /**      * Prints an array of integers to standard output.      *      *  @param  a the 1D array of integers      */      public   static   void  print ( int []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . printf ( "%9d " ,  a [ i ]);          }          StdOut . println ();      }               /**      * Reads a 2D array of integers from standard input and returns it.      *      *  @return  the 2D array of integers      */      public   static   int [][]  readInt2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          int [][]  a  =   new   int [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readInt ();              }          }          return  a ;      }      /**      * Print a 2D array of integers to standard output.      *      *  @param  a the 2D array of integers      */      public   static   void  print ( int [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  StdOut . printf ( "%9d " ,  a [ i ][ j ]);              }              StdOut . println ();          }      }      /**      * Reads a 1D array of booleans from standard input and returns it.      *      *  @return  the 1D array of booleans      */      public   static   boolean []  readBoolean1D ()   {          int  n  =   StdIn . readInt ();          boolean []  a  =   new   boolean [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             a [ i ]   =   StdIn . readBoolean ();          }          return  a ;      }      /**      * Prints a 1D array of booleans to standard output.      *      *  @param  a the 1D array of booleans      */      public   static   void  print ( boolean []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( a [ i ])   StdOut . print ( "1 " );              else        StdOut . print ( "0 " );          }          StdOut . println ();      }      /**      * Reads a 2D array of booleans from standard input and returns it.      *      *  @return  the 2D array of booleans      */      public   static   boolean [][]  readBoolean2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          boolean [][]  a  =   new   boolean [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readBoolean ();              }          }          return  a ;      }     /**      * Prints a 2D array of booleans to standard output.      *      *  @param  a the 2D array of booleans      */      public   static   void  print ( boolean [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( a [ i ][ j ])   StdOut . print ( "1 " );                  else           StdOut . print ( "0 " );              }              StdOut . println ();          }      }     /**      * Unit tests { @code  StdArrayIO}.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read and print an array of doubles          double []  a  =   StdArrayIO . readDouble1D ();          StdArrayIO . print ( a );          StdOut . println ();          // read and print a matrix of doubles          double [][]  b  =   StdArrayIO . readDouble2D ();          StdArrayIO . print ( b );          StdOut . println ();          // read and print a matrix of doubles          boolean [][]  d  =   StdArrayIO . readBoolean2D ();          StdArrayIO . print ( d );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/StdAudio.java edu/princeton/cs/algs4/StdAudio.java /******************************************************************************  *  Compilation:  javac StdAudio.java  *  Execution:    java StdAudio  *  Dependencies: none  *    *  Simple library for reading, writing, and manipulating .wav files.  *  *  *  Limitations  *  -----------  *    - Assumes the audio is monaural, little endian, with sampling rate  *      of 44,100  *    - check when reading .wav files from a .jar file ?  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  javax . sound . sampled . Clip ; import  java . io . File ; import  java . io . ByteArrayInputStream ; import  java . io . InputStream ; import  java . io . IOException ; import  java . net . URL ; import  javax . sound . sampled . AudioFileFormat ; import  javax . sound . sampled . AudioFormat ; import  javax . sound . sampled . AudioInputStream ; import  javax . sound . sampled . AudioSystem ; import  javax . sound . sampled . DataLine ; import  javax . sound . sampled . LineUnavailableException ; import  javax . sound . sampled . SourceDataLine ; import  javax . sound . sampled . UnsupportedAudioFileException ; import  javax . sound . sampled . LineListener ; import  javax . sound . sampled . LineEvent ; /**  *  Standard audio. This class provides a basic capability for

 *  creating, reading, and saving audio. 

 *  

 *  The audio format uses a sampling rate of 44,100 Hz, 16-bit, monaural.

 *

 *  

 *  For additional documentation, see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdAudio
 
{

    
/**

     *  The sample rate: 44,100 Hz for CD quality audio.

     */

    
public
 
static
 
final
 
int
 SAMPLE_RATE 
=
 
44100
;

    
private
 
static
 
final
 
int
 BYTES_PER_SAMPLE 
=
 
2
;
       
// 16-bit audio

    
private
 
static
 
final
 
int
 BITS_PER_SAMPLE 
=
 
16
;
       
// 16-bit audio

    
private
 
static
 
final
 
double
 MAX_16_BIT 
=
 
32768
;

    
private
 
static
 
final
 
int
 SAMPLE_BUFFER_SIZE 
=
 
4096
;

    
private
 
static
 
final
 
int
 MONO   
=
 
1
;

    
private
 
static
 
final
 
int
 STEREO 
=
 
2
;

    
private
 
static
 
final
 
boolean
 LITTLE_ENDIAN 
=
 
false
;

    
private
 
static
 
final
 
boolean
 BIG_ENDIAN    
=
 
true
;

    
private
 
static
 
final
 
boolean
 SIGNED        
=
 
true
;

    
private
 
static
 
final
 
boolean
 UNSIGNED      
=
 
false
;

    
private
 
static
 
SourceDataLine
 line
;
   
// to play the sound

    
private
 
static
 
byte
[]
 buffer
;
         
// our internal buffer

    
private
 
static
 
int
 bufferSize 
=
 
0
;
    
// number of samples currently in internal buffer

    
private
 
StdAudio
()
 
{

        
// can not instantiate

    
}

   

    
// static initializer

    
static
 
{

        init
();

    
}

    
// open up an audio stream

    
private
 
static
 
void
 init
()
 
{

        
try
 
{

            
// 44,100 Hz, 16-bit audio, mono, signed PCM, little endian

            
AudioFormat
 format 
=
 
new
 
AudioFormat
((
float
)
 SAMPLE_RATE
,
 BITS_PER_SAMPLE
,
 MONO
,
 SIGNED
,
 LITTLE_ENDIAN
);

            
DataLine
.
Info
 info 
=
 
new
 
DataLine
.
Info
(
SourceDataLine
.
class
,
 format
);

            line 
=
 
(
SourceDataLine
)
 
AudioSystem
.
getLine
(
info
);

            line
.
open
(
format
,
 SAMPLE_BUFFER_SIZE 
*
 BYTES_PER_SAMPLE
);

            

            
// the internal buffer is a fraction of the actual buffer size, this choice is arbitrary

            
// it gets divided because we can’t expect the buffered data to line up exactly with when

            
// the sound card decides to push out its samples.

            buffer 
=
 
new
 
byte
[
SAMPLE_BUFFER_SIZE 
*
 BYTES_PER_SAMPLE
/
3
];

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            
System
.
out
.
println
(
e
.
getMessage
());

        
}

        
// no sound gets made before this call

        line
.
start
();

    
}

    
// get an AudioInputStream object from a file

    
private
 
static
 
AudioInputStream
 getAudioInputStreamFromFile
(
String
 filename
)
 
{

        
if
 
(
filename 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“filename is null”
);

        
}

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
filename
);

            
if
 
(
file
.
exists
())
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
file
);

            
}

            
// resource relative to .class file

            
InputStream
 is1 
=
 
StdAudio
.
class
.
getResourceAsStream
(
filename
);

            
if
 
(
is1 
!=
 
null
)
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
is1
);

            
}

            
// resource relative to classloader root

            
InputStream
 is2 
=
 
StdAudio
.
class
.
getClassLoader
().
getResourceAsStream
(
filename
);

            
if
 
(
is2 
!=
 
null
)
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
is2
);

            
}

            
// give up

            
else
 
{

                
throw
 
new
 
IllegalArgumentException
(
“could not read ‘”
 
+
 filename 
+
 
“‘”
);

            
}

        
}

        
catch
 
(
IOException
 e
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“could not read ‘”
 
+
 filename 
+
 
“‘”
,
 e
);

        
}

        
catch
 
(
UnsupportedAudioFileException
 e
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“file of unsupported audio format: ‘”
 
+
 filename 
+
 
“‘”
,
 e
);

        
}

    
}

    
/**

     * Closes standard audio.

     */

    
public
 
static
 
void
 close
()
 
{

        line
.
drain
();

        line
.
stop
();

    
}

    

    
/**

     * Writes one sample (between -1.0 and +1.0) to standard audio.

     * If the sample is outside the range, it will be clipped.

     *

     * 
@param
  sample the sample to play

     * 
@throws
 IllegalArgumentException if the sample is {
@code
 Double.NaN}

     */

    
public
 
static
 
void
 play
(
double
 sample
)
 
{

        
if
 
(
Double
.
isNaN
(
sample
))
 
throw
 
new
 
IllegalArgumentException
(
“sample is NaN”
);

        
// clip if outside [-1, +1]

        
if
 
(
sample 
<   - 1.0 )  sample  =   - 1.0 ;          if   ( sample  >
 
+
1.0
)
 sample 
=
 
+
1.0
;

        
// convert to bytes

        
short
 s 
=
 
(
short
)
 
(
MAX_16_BIT 
*
 sample
);

        
if
 
(
sample 
==
 
1.0
)
 s 
=
 
Short
.
MAX_VALUE
;
   
// special case since 32768 not a short

        buffer
[
bufferSize
++
]
 
=
 
(
byte
)
 s
;

        buffer
[
bufferSize
++
]
 
=
 
(
byte
)
 
(

>>
 
8
);
   
// little endian

        
// send to sound card if buffer is full        

        
if
 
(
bufferSize 
>=
 buffer
.
length
)
 
{

            line
.
write
(
buffer
,
 
0
,
 buffer
.
length
);

            bufferSize 
=
 
0
;

        
}

    
}

    
/**

     * Writes the array of samples (between -1.0 and +1.0) to standard audio.

     * If a sample is outside the range, it will be clipped.

     *

     * 
@param
  samples the array of samples to play

     * 
@throws
 IllegalArgumentException if any sample is {
@code
 Double.NaN}

     * 
@throws
 IllegalArgumentException if {
@code
 samples} is {
@code
 null}

     */

    
public
 
static
 
void
 play
(
double
[]
 samples
)
 
{

        
if
 
(
samples 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to play() is null”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  samples . length ;  i ++ )   {             play ( samples [ i ]);          }      }      /**      * Reads audio samples from a file (in .wav or .au format) and returns      * them as a double array with values between -1.0 and +1.0.      * The audio file must be 16-bit with a sampling rate of 44,100.      * It can be mono or stereo.      *      *  @param   filename the name of the audio file      *  @return  the array of samples      */      public   static   double []  read ( String  filename )   {          // make sure that AudioFormat is 16-bit, 44,100 Hz, little endian          final   AudioInputStream  ais  =  getAudioInputStreamFromFile ( filename );          AudioFormat  audioFormat  =  ais . getFormat ();          // require sampling rate = 44,100 Hz          if   ( audioFormat . getSampleRate ()   !=  SAMPLE_RATE )   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only a sample rate of "   +  SAMPLE_RATE  +   " Hz\n"                                               +   "audio format: "   +  audioFormat );          }          // require 16-bit audio          if   ( audioFormat . getSampleSizeInBits ()   !=  BITS_PER_SAMPLE )   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only "   +  BITS_PER_SAMPLE  +   "-bit audio\n"                                               +   "audio format: "   +  audioFormat );          }          // require little endian          if   ( audioFormat . isBigEndian ())   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only audio stored using little endian\n"                                               +   "audio format: "   +  audioFormat );          }          byte []  bytes  =   null ;          try   {              int  bytesToRead  =  ais . available ();             bytes  =   new   byte [ bytesToRead ];              int  bytesRead  =  ais . read ( bytes );              if   ( bytesToRead  !=  bytesRead )   {                  throw   new   IllegalStateException ( "read only "   +  bytesRead  +   " of "   +  bytesToRead  +   " bytes" );                }          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not read '"   +  filename  +   "'" ,  ioe );          }          int  n  =  bytes . length ;          // little endian, mono          if   ( audioFormat . getChannels ()   ==  MONO )   {              double []  data  =   new   double [ n / 2 ];              for   ( int  i  =   0 ;  i  <  n / 2 ;  i ++ )   {                  // little endian, mono                 data [ i ]   =   (( short )   ((( bytes [ 2 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 2 * i ]   &   0xFF )))   /   (( double )  MAX_16_BIT );              }              return  data ;          }          // little endian, stereo          else   if   ( audioFormat . getChannels ()   ==  STEREO )   {              double []  data  =   new   double [ n / 4 ];              for   ( int  i  =   0 ;  i  <  n / 4 ;  i ++ )   {                  double  left   =   (( short )   ((( bytes [ 4 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * i  +   0 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );                  double  right  =   (( short )   ((( bytes [ 4 * i + 3 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * i  +   2 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );                 data [ i ]   =   ( left  +  right )   /   2.0 ;              }              return  data ;          }          // TODO: handle big endian (or other formats)          else   throw   new   IllegalStateException ( "audio format is neither mono or stereo" );      }      /**      * Saves the double array as an audio file (using .wav or .au format).      *      *  @param   filename the name of the audio file      *  @param   samples the array of samples      *  @throws  IllegalArgumentException if unable to save { @code  filename}      *  @throws  IllegalArgumentException if { @code  samples} is { @code  null}      *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}      *  @throws  IllegalArgumentException if { @code  filename} extension is not { @code  .wav}      *         or { @code  .au}      */      public   static   void  save ( String  filename ,   double []  samples )   {          if   ( filename  ==   null )   {              throw   new   IllegalArgumentException ( "filenameis null" );          }          if   ( samples  ==   null )   {              throw   new   IllegalArgumentException ( "samples[] is null" );          }          // assumes 16-bit samples with sample rate = 44,100 Hz          // use 16-bit audio, mono, signed PCM, little Endian          AudioFormat  format  =   new   AudioFormat ( SAMPLE_RATE ,   16 ,  MONO ,  SIGNED ,  LITTLE_ENDIAN );          byte []  data  =   new   byte [ 2   *  samples . length ];          for   ( int  i  =   0 ;  i  <  samples . length ;  i ++ )   {              int  temp  =   ( short )   ( samples [ i ]   *  MAX_16_BIT );              if   ( samples [ i ]   ==   1.0 )  temp  =   Short . MAX_VALUE ;     // special case since 32768 not a short             data [ 2 * i  +   0 ]   =   ( byte )  temp ;             data [ 2 * i  +   1 ]   =   ( byte )   ( temp  >>
 
8
);
   
// little endian

        
}

        
// now save the file

        
try
 
{

            
ByteArrayInputStream
 bais 
=
 
new
 
ByteArrayInputStream
(
data
);

            
AudioInputStream
 ais 
=
 
new
 
AudioInputStream
(
bais
,
 format
,
 samples
.
length
);

            
if
 
(
filename
.
endsWith
(
“.wav”
)
 
||
 filename
.
endsWith
(
“.WAV”
))
 
{

                
AudioSystem
.
write
(
ais
,
 
AudioFileFormat
.
Type
.
WAVE
,
 
new
 
File
(
filename
));

            
}

            
else
 
if
 
(
filename
.
endsWith
(
“.au”
)
 
||
 filename
.
endsWith
(
“.AU”
))
 
{

                
AudioSystem
.
write
(
ais
,
 
AudioFileFormat
.
Type
.
AU
,
 
new
 
File
(
filename
));

            
}

            
else
 
{

                
throw
 
new
 
IllegalArgumentException
(
“file type for saving must be .wav or .au”
);

            
}

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“unable to save file ‘”
 
+
 filename 
+
 
“‘”
,
 ioe
);

        
}

    
}

    
/**

     * Plays an audio file (in .wav, .mid, or .au format) in a background thread.

     *

     * 
@param
 filename the name of the audio file

     * 
@throws
 IllegalArgumentException if unable to play {
@code
 filename}

     * 
@throws
 IllegalArgumentException if {
@code
 filename} is {
@code
 null}

     */

    
public
 
static
 
synchronized
 
void
 play
(
final
 
String
 filename
)
 
{

        
new
 
Thread
(
new
 
Runnable
()
 
{

            
public
 
void
 run
()
 
{

                
AudioInputStream
 ais 
=
 getAudioInputStreamFromFile
(
filename
);

                stream
(
ais
);

            
}

        
}).
start
();

    
}

    
// https://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html

    
// play a wav or aif file

    
// javax.sound.sampled.Clip fails for long clips (on some systems), perhaps because

    
// JVM closes (see remedy in loop)

    
private
 
static
 
void
 stream
(
AudioInputStream
 ais
)
 
{

        
SourceDataLine
 line 
=
 
null
;

        
int
 BUFFER_SIZE 
=
 
4096
;
 
// 4K buffer

        
try
 
{

            
AudioFormat
 audioFormat 
=
 ais
.
getFormat
();

            
DataLine
.
Info
 info 
=
 
new
 
DataLine
.
Info
(
SourceDataLine
.
class
,
 audioFormat
);

            line 
=
 
(
SourceDataLine
)
 
AudioSystem
.
getLine
(
info
);

            line
.
open
(
audioFormat
);

            line
.
start
();

            
byte
[]
 samples 
=
 
new
 
byte
[
BUFFER_SIZE
];

            
int
 count 
=
 
0
;

            
while
 
((
count 
=
 ais
.
read
(
samples
,
 
0
,
 BUFFER_SIZE
))
 
!=
 

1
)
 
{

                line
.
write
(
samples
,
 
0
,
 count
);

            
}

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
finally
 
{

            
if
 
(
line 
!=
 
null
)
 
{

                line
.
drain
();

                line
.
close
();

            
}

        
}

    
}

    
/**

     * Loops an audio file (in .wav, .mid, or .au format) in a background thread.

     *

     * 
@param
 filename the name of the audio file

     * 
@throws
 IllegalArgumentException if {
@code
 filename} is {
@code
 null}

     */

    
public
 
static
 
synchronized
 
void
 loop
(
String
 filename
)
 
{

        
if
 
(
filename 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
();

        
final
 
AudioInputStream
 ais 
=
 getAudioInputStreamFromFile
(
filename
);

        
try
 
{

            
Clip
 clip 
=
 
AudioSystem
.
getClip
();

            
// Clip clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));

            clip
.
open
(
ais
);

            clip
.
loop
(
Clip
.
LOOP_CONTINUOUSLY
);

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
// keep JVM open

        
new
 
Thread
(
new
 
Runnable
()
 
{

            
public
 
void
 run
()
 
{

                
while
 
(
true
)
 
{

                    
try
 
{

                       
Thread
.
sleep
(
1000
);

                    
}

                    
catch
 
(
InterruptedException
 e
)
 
{

                        e
.
printStackTrace
();

                    
}

                
}

            
}

        
}).
start
();

    
}

   
/***************************************************************************

    * Unit tests {
@code
 StdAudio}.

    ***************************************************************************/

    
// create a note (sine wave) of the given frequency (Hz), for the given

    
// duration (seconds) scaled to the given volume (amplitude)

    
private
 
static
 
double
[]
 note
(
double
 hz
,
 
double
 duration
,
 
double
 amplitude
)
 
{

        
int
 n 
=
 
(
int
)
 
(
StdAudio
.
SAMPLE_RATE 
*
 duration
);

        
double
[]
 a 
=
 
new
 
double
[
n
+
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<=  n ;  i ++ )             a [ i ]   =  amplitude  *   Math . sin ( 2   *   Math . PI  *  i  *  hz  /   StdAudio . SAMPLE_RATE );          return  a ;      }      /**      * Test client - play an A major scale to standard audio.      *      *  @param  args the command-line arguments      */      /**      * Test client - play an A major scale to standard audio.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {                   // 440 Hz for 1 sec          double  freq  =   440.0 ;          for   ( int  i  =   0 ;  i  <=   StdAudio . SAMPLE_RATE ;  i ++ )   {              StdAudio . play ( 0.5   *   Math . sin ( 2 * Math . PI  *  freq  *  i  /   StdAudio . SAMPLE_RATE ));          }                   // scale increments          int []  steps  =   {   0 ,   2 ,   4 ,   5 ,   7 ,   9 ,   11 ,   12   };          for   ( int  i  =   0 ;  i  <  steps . length ;  i ++ )   {              double  hz  =   440.0   *   Math . pow ( 2 ,  steps [ i ]   /   12.0 );              StdAudio . play ( note ( hz ,   1.0 ,   0.5 ));          }          // need to call this in non-interactive stuff so the program doesn't terminate          // until all the sound leaves the speaker.          StdAudio . close ();        } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/StdDraw.java edu/princeton/cs/algs4/StdDraw.java /******************************************************************************  *  Compilation:  javac StdDraw.java  *  Execution:    java StdDraw  *  Dependencies: none  *  *  Standard drawing library. This class provides a basic capability for  *  creating drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of geometric shapes (e.g.,  *  points, lines, circles, rectangles) in a window on your computer  *  and to save the drawings to a file.  *  *  Todo  *  ----  *    -  Add support for gradient fill, etc.  *    -  Fix setCanvasSize() so that it can be called only once.  *    -  Should setCanvasSize() reset xScale(), yScale(), penRadius(),  *       penColor(), and font()  *    -  On some systems, drawing a line (or other shape) that extends way  *       beyond canvas (e.g., to infinity) dimensions does not get drawn.  *  *  Remarks  *  -------  *    -  don't use AffineTransform for rescaling since it inverts  *       images and strings  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . awt . BasicStroke ; import  java . awt . Color ; import  java . awt . Component ; import  java . awt . FileDialog ; import  java . awt . Font ; import  java . awt . FontMetrics ; import  java . awt . Graphics ; import  java . awt . Graphics2D ; import  java . awt . Image ; import  java . awt . MediaTracker ; import  java . awt . RenderingHints ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . MouseEvent ; import  java . awt . event . MouseListener ; import  java . awt . event . MouseMotionListener ; import  java . awt . event . KeyEvent ; import  java . awt . event . KeyListener ; import  java . awt . geom . Arc2D ; import  java . awt . geom . Ellipse2D ; import  java . awt . geom . GeneralPath ; import  java . awt . geom . Line2D ; import  java . awt . geom . Rectangle2D ; import  java . awt . image . BufferedImage ; import  java . awt . image . DirectColorModel ; import  java . awt . image . WritableRaster ; import  java . io . File ; import  java . io . IOException ; import  java . net . MalformedURLException ; import  java . net . URL ; import  java . util . LinkedList ; import  java . util . TreeSet ; import  java . util . NoSuchElementException ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . KeyStroke ; /**  *  The { @code  StdDraw} class provides a basic capability for  *  creating drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of points, lines, squares,   *  circles, and other geometric shapes in a window on your computer and  *  to save the drawings to a file. Standard drawing also includes  *  facilities for text, color, pictures, and animation, along with  *  user interaction via the keyboard and mouse.  *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdDraw.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdDraw.java

 *  and put a copy in your working directory.

 *  

 *  Now, type the following short program into your editor:

 *  


 *   public class TestStdDraw {

 *       public static void main(String[] args) {

 *           StdDraw.setPenRadius(0.05);

 *           StdDraw.setPenColor(StdDraw.BLUE);

 *           StdDraw.point(0.5, 0.5);

 *           StdDraw.setPenColor(StdDraw.MAGENTA);

 *           StdDraw.line(0.2, 0.2, 0.8, 0.2);

 *       }

 *   }

 *  

 *  If you compile and execute the program, you should see a window

 *  appear with a thick magenta line and a blue point.

 *  This program illustrates the two main types of methods in standard

 *  drawing—methods that draw geometric shapes and methods that

 *  control drawing parameters.

 *  The methods {
@code
 StdDraw.line()} and {
@code
 StdDraw.point()}

 *  draw lines and points; the methods {
@code
 StdDraw.setPenRadius()}

 *  and {
@code
 StdDraw.setPenColor()} control the line thickness and color.

 *  

 *  Points and lines.

 *  You can draw points and line segments with the following methods:

 *  

     *  

  •  {
    @link
     #point(double x, double y)}

     *  

  •  {
    @link
     #line(double x1, double y1, double x2, double y2)}

     *  

 *  

 *  The x– and y-coordinates must be in the drawing area

 *  (between 0 and 1 and by default) or the points and lines will not be visible.

 *  

 *  Squares, circles, rectangles, and ellipses.

 *  You can draw squares, circles, rectangles, and ellipses using

 *  the following methods:

 *  

     *  

  •  {
    @link
     #circle(double x, double y, double radius)}

     *  

  •  {
    @link
     #ellipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}

     *  

  •  {
    @link
     #square(double x, double y, double halfLength)}

     *  

  •  {
    @link
     #rectangle(double x, double y, double halfWidth, double halfHeight)}

     *  

 *  

 *  All of these methods take as arguments the location and size of the shape.

 *  The location is always specified by the x– and y-coordinates

 *  of its center.

 *  The size of a circle is specified by its radius and the size of an ellipse is

 *  specified by the lengths of its semi-major and semi-minor axes.

 *  The size of a square or rectangle is specified by its half-width or half-height.

 *  The convention for drawing squares and rectangles is parallel to those for

 *  drawing circles and ellipses, but may be unexpected to the uninitiated.

 *  

 *  The methods above trace outlines of the given shapes. The following methods

 *  draw filled versions:

 *  

     *  

  •  {
    @link
     #filledCircle(double x, double y, double radius)}

     *  

  •  {
    @link
     #filledEllipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}

     *  

  •  {
    @link
     #filledSquare(double x, double y, double radius)}

     *  

  •  {
    @link
     #filledRectangle(double x, double y, double halfWidth, double halfHeight)}

     *  

 *  

 *  Circular arcs.

 *  You can draw circular arcs with the following method:

 *  

     *  

  •  {
    @link
     #arc(double x, double y, double radius, double angle1, double angle2)}

     *  

 *  

 *  The arc is from the circle centered at (xy) of the specified radius.

 *  The arc extends from angle1 to angle2. By convention, the angles are

 *  polar (counterclockwise angle from the x-axis)

 *  and represented in degrees. For example, {
@code
 StdDraw.arc(0.0, 0.0, 1.0, 0, 90)}

 *  draws the arc of the unit circle from 3 o’clock (0 degrees) to 12 o’clock (90 degrees).

 *  

 *  Polygons.

 *  You can draw polygons with the following methods:

 *  

     *  

  •  {
    @link
     #polygon(double[] x, double[] y)}

     *  

  •  {
    @link
     #filledPolygon(double[] x, double[] y)}

     *  

 *  

 *  The points in the polygon are ({
@code
 x[i]}, {
@code
 y[i]}).

 *  For example, the following code fragment draws a filled diamond

 *  with vertices (0.1, 0.2), (0.2, 0.3), (0.3, 0.2), and (0.2, 0.1):

 *  


 *   double[] x = { 0.1, 0.2, 0.3, 0.2 };

 *   double[] y = { 0.2, 0.3, 0.2, 0.1 };

 *   StdDraw.filledPolygon(x, y);

 *  

 *  

 *  Pen size.

 *  The pen is circular, so that when you set the pen radius to r

 *  and draw a point, you get a circle of radius r. Also, lines are

 *  of thickness 2r and have rounded ends. The default pen radius

 *  is 0.005 and is not affected by coordinate scaling. This default pen

 *  radius is about 1/200 the width of the default canvas, so that if

 *  you draw 100 points equally spaced along a horizontal or vertical line,

 *  you will be able to see individual circles, but if you draw 200 such

 *  points, the result will look like a line.

 *  

     *  

  •  {
    @link
     #setPenRadius(double radius)}

     *  

 *  

 *  For example, {
@code
 StdDraw.setPenRadius(0.025)} makes

 *  the thickness of the lines and the size of the points to be five times

 *  the 0.005 default.

 *  To draw points with the minimum possible radius (one pixel on typical

 *  displays), set the pen radius to 0.0.

 *  

 *  Pen color.

 *  All geometric shapes (such as points, lines, and circles) are drawn using

 *  the current pen color. By default, it is black.

 *  You can change the pen color with the following methods:

 *  

     *  

  •  {
    @link
     #setPenColor(int red, int green, int blue)}

     *  

  •  {
    @link
     #setPenColor(Color color)}

     *  

 *  

 *  The first method allows you to specify colors using the RGB color system.

 *  This color picker

 *  is a convenient way to find a desired color.

 *  The second method allows you to specify colors using the

 *  {
@link
 Color} data type that is discussed in Chapter 3. Until then,

 *  you can use this method with one of these predefined colors in standard drawing:

 *  {
@link
 #BLACK}, {
@link
 #BLUE}, {
@link
 #CYAN}, {
@link
 #DARK_GRAY}, {
@link
 #GRAY},

 *  {
@link
 #GREEN}, {
@link
 #LIGHT_GRAY}, {
@link
 #MAGENTA}, {
@link
 #ORANGE},

 *  {
@link
 #PINK}, {
@link
 #RED}, {
@link
 #WHITE}, {
@link
 #YELLOW},

 *  {
@link
 #BOOK_BLUE}, {
@link
 #BOOK_LIGHT_BLUE}, {
@link
 #BOOK_RED}, and

 *  {
@link
 #PRINCETON_ORANGE}.

 *  For example, {
@code
 StdDraw.setPenColor(StdDraw.MAGENTA)} sets the

 *  pen color to magenta.

 *  

 *  Canvas size.

 *  By default, all drawing takes places in a 512-by-512 canvas.

 *  The canvas does not include the window title or window border.

 *  You can change the size of the canvas with the following method:

 *  

     *  

  •  {
    @link
     #setCanvasSize(int width, int height)}

     *  

 *  

 *  This sets the canvas size to be width-by-height pixels.

 *  It also erases the current drawing and resets the coordinate system,

 *  pen radius, pen color, and font back to their default values.

 *  Ordinarly, this method is called once, at the very beginning of a program.

 *  For example, {
@code
 StdDraw.setCanvasSize(800, 800)}

 *  sets the canvas size to be 800-by-800 pixels.

 *  

 *  Canvas scale and coordinate system.

 *  By default, all drawing takes places in the unit square, with (0, 0) at

 *  lower left and (1, 1) at upper right. You can change the default

 *  coordinate system with the following methods:

 *  

     *  

  •  {
    @link
     #setXscale(double xmin, double xmax)}

     *  

  •  {
    @link
     #setYscale(double ymin, double ymax)}

     *  

  •  {
    @link
     #setScale(double min, double max)}

     *  

 *  

 *  The arguments are the coordinates of the minimum and maximum 

 *  x– or y-coordinates that will appear in the canvas.

 *  For example, if you  wish to use the default coordinate system but

 *  leave a small margin, you can call {
@code
 StdDraw.setScale(-.05, 1.05)}.

 *  

 *  These methods change the coordinate system for subsequent drawing

 *  commands; they do not affect previous drawings.

 *  These methods do not change the canvas size; so, if the x

 *  and y-scales are different, squares will become rectangles

 *  and circles will become ellipses.

 *  

 *  Text.

 *  You can use the following methods to annotate your drawings with text:

 *  

     *  

  •  {
    @link
     #text(double x, double y, String text)}

     *  

  •  {
    @link
     #text(double x, double y, String text, double degrees)}

     *  

  •  {
    @link
     #textLeft(double x, double y, String text)}

     *  

  •  {
    @link
     #textRight(double x, double y, String text)}

     *  

 *  

 *  The first two methods write the specified text in the current font,

 *  centered at (xy).

 *  The second method allows you to rotate the text.

 *  The last two methods either left- or right-align the text at (xy).

 *  

 *  The default font is a Sans Serif font with point size 16.

 *  You can use the following method to change the font:

 *  

     *  

  •  {
    @link
     #setFont(Font font)}

     *  

 *  

 *  You use the {
@link
 Font} data type to specify the font. This allows you to

 *  choose the face, size, and style of the font. For example, the following

 *  code fragment sets the font to Arial Bold, 60 point.

 *  


 *   Font font = new Font("Arial", Font.BOLD, 60);

 *   StdDraw.setFont(font);

 *   StdDraw.text(0.5, 0.5, "Hello, World");

 *  

 *  

 *  Images.

 *  You can use the following methods to add images to your drawings:

 *  

     *  

  •  {
    @link
     #picture(double x, double y, String filename)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double degrees)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double scaledWidth, double scaledHeight)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees)}

     *  

 *  

 *  These methods draw the specified image, centered at (xy).

 *  The supported image formats are JPEG, PNG, and GIF.

 *  The image will display at its native size, independent of the coordinate system.

 *  Optionally, you can rotate the image a specified number of degrees counterclockwise

 *  or rescale it to fit snugly inside a width-by-height bounding box.

 *  

 *  Saving to a file.

 *  You save your image to a file using the File → Save menu option.

 *  You can also save a file programatically using the following method:

 *  

     *  

  •  {
    @link
     #save(String filename)}

     *  

 *  

 *  The supported image formats are JPEG and PNG. The filename must have either the

 *  extension   or  .

 *  We recommend using PNG for drawing that consist solely of geometric shapes and JPEG 

 *  for drawings that contains pictures.

 *  

 *  Clearing the canvas.

 *  To clear the entire drawing canvas, you can use the following methods:

 *  

     *  

  •  {
    @link
     #clear()}

     *  

  •  {
    @link
     #clear(Color color)}

     *  

 *  

 *  The first method clears the canvas to white; the second method

 *  allows you to specify a color of your choice. For example,

 *  {
@code
 StdDraw.clear(StdDraw.LIGHT_GRAY)} clears the canvas to a shade

 *  of gray.

 *  

 *  Computer animations and double buffering.

 *  Double buffering is one of the most powerful features of standard drawing,

 *  enabling computer animations.

 *  The following methods control the way in which objects are drawn:

 *  

     *  

  •  {
    @link
     #enableDoubleBuffering()}

     *  

  •  {
    @link
     #disableDoubleBuffering()}

     *  

  •  {
    @link
     #show()}

     *  

  •  {
    @link
     #pause(int t)}

     *  

 *  

 *  By default, double buffering is disabled, which means that as soon as you

 *  call a drawing

 *  method—such as {
@code
 point()} or {
@code
 line()}—the

 *  results appear on the screen.

 *  

 *  When double buffering is enabled by calling {
@link
 #enableDoubleBuffering()},

 *  all drawing takes place on the offscreen canvas. The offscreen canvas

 *  is not displayed. Only when you call

 *  {
@link
 #show()} does your drawing get copied from the offscreen canvas to

 *  the onscreen canvas, where it is displayed in the standard drawing window. You 

 *  can think of double buffering as collecting all of the lines, points, shapes,

 *  and text that you tell it to draw, and then drawing them all

 *  simultaneously, upon request.

 *  

 *  The most important use of double buffering is to produce computer

 *  animations, creating the illusion of motion by rapidly

 *  displaying static drawings. To produce an animation, repeat

 *  the following four steps:

 *  

     *  

  •  Clear the offscreen canvas.

     *  

  •  Draw objects on the offscreen canvas.

     *  

  •  Copy the offscreen canvas to the onscreen canvas.

     *  

  •  Wait for a short while.

     *  

 *  

 *  The {
@link
 #clear()}, {
@link
 #show()}, and {
@link
 #pause(int t)} methods

 *  support the first, third, and fourth of these steps, respectively.

 *  

 *  For example, this code fragment animates two balls moving in a circle.

 *  


 *   StdDraw.setScale(-2, +2);

 *   StdDraw.enableDoubleBuffering();

 *

 *   for (double t = 0.0; true; t += 0.02) {

 *       double x = Math.sin(t);

 *       double y = Math.cos(t);

 *       StdDraw.clear();

 *       StdDraw.filledCircle(x, y, 0.05);

 *       StdDraw.filledCircle(-x, -y, 0.05);

 *       StdDraw.show();

 *       StdDraw.pause(20);

 *   }

 *  

 *  

 *  Keyboard and mouse inputs.

 *  Standard drawing has very basic support for keyboard and mouse input.

 *  It is much less powerful than most user interface libraries provide, but also much simpler.

 *  You can use the following methods to intercept mouse events:

 *  

     *  

  •  {
    @link
     #isMousePressed()}

     *  

  •  {
    @link
     #mouseX()}

     *  

  •  {
    @link
     #mouseY()}

     *  

 *  

 *  The first method tells you whether a mouse button is currently being pressed.

 *  The last two methods tells you the x– and y-coordinates of the mouse’s

 *  current position, using the same coordinate system as the canvas (the unit square, by default).

 *  You should use these methods in an animation loop that waits a short while before trying

 *  to poll the mouse for its current state.

 *  You can use the following methods to intercept keyboard events:

 *  

     *  

  •  {
    @link
     #hasNextKeyTyped()}

     *  

  •  {
    @link
     #nextKeyTyped()}

     *  

  •  {
    @link
     #isKeyPressed(int keycode)}

     *  

 *  

 *  If the user types lots of keys, they will be saved in a list until you process them.

 *  The first method tells you whether the user has typed a key (that your program has

 *  not yet processed).

 *  The second method returns the next key that the user typed (that your program has

 *  not yet processed) and removes it from the list of saved keystrokes.

 *  The third method tells you whether a key is currently being pressed.

 *  

 *  Accessing control parameters.

 *  You can use the following methods to access the current pen color, pen radius,

 *  and font:

 *  

     *  

  •  {
    @link
     #getPenColor()}

     *  

  •  {
    @link
     #getPenRadius()}

     *  

  •  {
    @link
     #getFont()}

     *  

 *  

 *  These methods are useful when you want to temporarily change a

 *  control parameter and reset it back to its original value.

 *  

 *  Corner cases.

 *  Here are some corner cases.

 *  

     *  

  •  Drawing an object outside (or partly outside) the canvas is permitted.

     *       However, only the part of the object that appears inside the canvas

     *       will be visible.

     *  

  •  Any method that is passed a {
    @code
     null} argument will throw an

     *       {
    @link
     IllegalArgumentException}.

     *  

  •  Any method that is passed a {
    @link
     Double#NaN},

     *       {
    @link
     Double#POSITIVE_INFINITY}, or {
    @link
     Double#NEGATIVE_INFINITY}

     *       argument will throw an {
    @link
     IllegalArgumentException}.

     *  

  •  Due to floating-point issues, an object drawn with an x– or

     *       y-coordinate that is way outside the canvas (such as the line segment

     *       from (0.5, –10^308) to (0.5, 10^308) may not be visible even in the

     *       part of the canvas where it should be.

     *  

 *  

 *  Performance tricks.

 *  Standard drawing is capable of drawing large amounts of data.

 *  Here are a few tricks and tips:

 *  

     *  

  •  Use double buffering for static drawing with a large

     *       number of objects.

     *       That is, call {
    @link
     #enableDoubleBuffering()} before

     *       the sequence of drawing commands and call {
    @link
     #show()} afterwards.

     *       Incrementally displaying a complex drawing while it is being

     *       created can be intolerably inefficient on many computer systems.

     *  

  •  When drawing computer animations, call {
    @code
     show()}

     *       only once per frame, not after drawing each individual object.

     *  

  •  If you call {
    @code
     picture()} multiple times with the same filename,

     *       Java will cache the image, so you do not incur the cost of reading

     *       from a file each time.

     *  

 *  

 *  Known bugs and issues.

 *  

     *  

  •  The {
    @code
     picture()} methods may not draw the portion of the image that is

     *       inside the canvas if the center point (xy) is outside the

     *       canvas.

     *       This bug appears only on some systems.

     *  

 *  

 *  Reference.

 *  For additional documentation,

 *  see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdDraw
 
implements
 
ActionListener
,
 
MouseListener
,
 
MouseMotionListener
,
 
KeyListener
 
{

    
/**

     *  The color black.

     */

    
public
 
static
 
final
 
Color
 BLACK 
=
 
Color
.
BLACK
;

    
/**

     *  The color blue.

     */

    
public
 
static
 
final
 
Color
 BLUE 
=
 
Color
.
BLUE
;

    
/**

     *  The color cyan.

     */

    
public
 
static
 
final
 
Color
 CYAN 
=
 
Color
.
CYAN
;

    
/**

     *  The color dark gray.

     */

    
public
 
static
 
final
 
Color
 DARK_GRAY 
=
 
Color
.
DARK_GRAY
;

    
/**

     *  The color gray.

     */

    
public
 
static
 
final
 
Color
 GRAY 
=
 
Color
.
GRAY
;

    
/**

     *  The color green.

     */

    
public
 
static
 
final
 
Color
 GREEN  
=
 
Color
.
GREEN
;

    
/**

     *  The color light gray.

     */

    
public
 
static
 
final
 
Color
 LIGHT_GRAY 
=
 
Color
.
LIGHT_GRAY
;

    
/**

     *  The color magenta.

     */

    
public
 
static
 
final
 
Color
 MAGENTA 
=
 
Color
.
MAGENTA
;

    
/**

     *  The color orange.

     */

    
public
 
static
 
final
 
Color
 ORANGE 
=
 
Color
.
ORANGE
;

    
/**

     *  The color pink.

     */

    
public
 
static
 
final
 
Color
 PINK 
=
 
Color
.
PINK
;

    
/**

     *  The color red.

     */

    
public
 
static
 
final
 
Color
 RED 
=
 
Color
.
RED
;

    
/**

     *  The color white.

     */

    
public
 
static
 
final
 
Color
 WHITE 
=
 
Color
.
WHITE
;

    
/**

     *  The color yellow.

     */

    
public
 
static
 
final
 
Color
 YELLOW 
=
 
Color
.
YELLOW
;

    
/**

     * Shade of blue used in Introduction to Programming in Java.

     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).

     */

    
public
 
static
 
final
 
Color
 BOOK_BLUE 
=
 
new
 
Color
(
9
,
 
90
,
 
166
);

    
/**

     * Shade of light blue used in Introduction to Programming in Java.

     * The RGB values are approximately (103, 198, 243).

     */

    
public
 
static
 
final
 
Color
 BOOK_LIGHT_BLUE 
=
 
new
 
Color
(
103
,
 
198
,
 
243
);

    
/**

     * Shade of red used in Algorithms, 4th edition.

     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).

     */

    
public
 
static
 
final
 
Color
 BOOK_RED 
=
 
new
 
Color
(
150
,
 
35
,
 
31
);

    
/**

     * Shade of orange used in Princeton University’s identity.

     * It is PMS 158. The RGB values are approximately (245, 128, 37).

     */

    
public
 
static
 
final
 
Color
 PRINCETON_ORANGE 
=
 
new
 
Color
(
245
,
 
128
,
 
37
);

    
// default colors

    
private
 
static
 
final
 
Color
 DEFAULT_PEN_COLOR   
=
 BLACK
;

    
private
 
static
 
final
 
Color
 DEFAULT_CLEAR_COLOR 
=
 WHITE
;

    
// current pen color

    
private
 
static
 
Color
 penColor
;

    
// default canvas size is DEFAULT_SIZE-by-DEFAULT_SIZE

    
private
 
static
 
final
 
int
 DEFAULT_SIZE 
=
 
512
;

    
private
 
static
 
int
 width  
=
 DEFAULT_SIZE
;

    
private
 
static
 
int
 height 
=
 DEFAULT_SIZE
;

    
// default pen radius

    
private
 
static
 
final
 
double
 DEFAULT_PEN_RADIUS 
=
 
0.002
;

    
// current pen radius

    
private
 
static
 
double
 penRadius
;

    
// show we draw immediately or wait until next show?

    
private
 
static
 
boolean
 defer 
=
 
false
;

    
// boundary of drawing canvas, 0% border

    
// private static final double BORDER = 0.05;

    
private
 
static
 
final
 
double
 BORDER 
=
 
0.00
;

    
private
 
static
 
final
 
double
 DEFAULT_XMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMAX 
=
 
1.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMAX 
=
 
1.0
;

    
private
 
static
 
double
 xmin
,
 ymin
,
 xmax
,
 ymax
;

    
// for synchronization

    
private
 
static
 
Object
 mouseLock 
=
 
new
 
Object
();

    
private
 
static
 
Object
 keyLock 
=
 
new
 
Object
();

    
// default font

    
private
 
static
 
final
 
Font
 DEFAULT_FONT 
=
 
new
 
Font
(
“SansSerif”
,
 
Font
.
PLAIN
,
 
16
);

    
// current font

    
private
 
static
 
Font
 font
;

    
// double buffered graphics

    
private
 
static
 
BufferedImage
 offscreenImage
,
 onscreenImage
;

    
private
 
static
 
Graphics2D
 offscreen
,
 onscreen
;

    
// singleton for callbacks: avoids generation of extra .class files

    
private
 
static
 
StdDraw
 std 
=
 
new
 
StdDraw
();

    
// the frame for drawing to the screen

    
private
 
static
 
JFrame
 frame
;

    
// mouse state

    
private
 
static
 
boolean
 isMousePressed 
=
 
false
;

    
private
 
static
 
double
 mouseX 
=
 
0
;

    
private
 
static
 
double
 mouseY 
=
 
0
;

    
// queue of typed key characters

    
private
 
static
 
LinkedList
< Character >
 keysTyped 
=
 
new
 
LinkedList
< Character >
();

    
// set of key codes currently pressed down

    
private
 
static
 
TreeSet
< Integer >
 keysDown 
=
 
new
 
TreeSet
< Integer >
();

    
// singleton pattern: client can’t instantiate

    
private
 
StdDraw
()
 
{
 
}

    
// static initializer

    
static
 
{

        init
();

    
}

    
/**

     * Sets the canvas (drawing area) to be 512-by-512 pixels.

     * This also erases the current drawing and resets the coordinate system,

     * pen radius, pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning

     * of a program.

     */

    
public
 
static
 
void
 setCanvasSize
()
 
{

        setCanvasSize
(
DEFAULT_SIZE
,
 DEFAULT_SIZE
);

    
}

    
/**

     * Sets the canvas (drawing area) to be width-by-height pixels.

     * This also erases the current drawing and resets the coordinate system,

     * pen radius, pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning

     * of a program.

     *

     * 
@param
  canvasWidth the width as a number of pixels

     * 
@param
  canvasHeight the height as a number of pixels

     * 
@throws
 IllegalArgumentException unless both {
@code
 canvasWidth} and

     *         {
@code
 canvasHeight} are positive

     */

    
public
 
static
 
void
 setCanvasSize
(
int
 canvasWidth
,
 
int
 canvasHeight
)
 
{

        
if
 
(
canvasWidth 
<=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );          if   ( canvasHeight  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );         width  =  canvasWidth ;         height  =  canvasHeight ;         init ();      }      // init      private   static   void  init ()   {          if   ( frame  !=   null )  frame . setVisible ( false );         frame  =   new   JFrame ();         offscreenImage  =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );         onscreenImage   =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );         offscreen  =  offscreenImage . createGraphics ();         onscreen   =  onscreenImage . createGraphics ();         offscreen . scale ( 2.0 ,   2.0 );    // since we made it 2x as big         setXscale ();         setYscale ();         offscreen . setColor ( DEFAULT_CLEAR_COLOR );         offscreen . fillRect ( 0 ,   0 ,  width ,  height );         setPenColor ();         setPenRadius ();         setFont ();         clear ();          // add antialiasing          RenderingHints  hints  =   new   RenderingHints ( RenderingHints . KEY_ANTIALIASING ,                                                    RenderingHints . VALUE_ANTIALIAS_ON );         hints . put ( RenderingHints . KEY_RENDERING ,   RenderingHints . VALUE_RENDER_QUALITY );         offscreen . addRenderingHints ( hints );          // frame stuff          RetinaImageIcon  icon  =   new   RetinaImageIcon ( onscreenImage );          JLabel  draw  =   new   JLabel ( icon );         draw . addMouseListener ( std );         draw . addMouseMotionListener ( std );         frame . setContentPane ( draw );         frame . addKeyListener ( std );      // JLabel cannot get keyboard focus         frame . setFocusTraversalKeysEnabled ( false );    // allow VK_TAB with isKeyPressed()         frame . setResizable ( false );         frame . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );              // closes all windows          // frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);      // closes only current window         frame . setTitle ( "Standard Draw" );         frame . setJMenuBar ( createMenuBar ());         frame . pack ();         frame . requestFocusInWindow ();         frame . setVisible ( true );      }      // create the menu bar (changed to private)      private   static   JMenuBar  createMenuBar ()   {          JMenuBar  menuBar  =   new   JMenuBar ();          JMenu  menu  =   new   JMenu ( "File" );         menuBar . add ( menu );          JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );         menuItem1 . addActionListener ( std );          // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()         menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                  Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));         menu . add ( menuItem1 );          return  menuBar ;      }     /***************************************************************************     *  User and screen coordinate systems.     ***************************************************************************/      // throw an IllegalArgumentException if x is NaN or infinite      private   static   void  validate ( double  x ,   String  name )   {          if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );          if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNonnegative ( double  x ,   String  name )   {          if   ( x  <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNotNull ( Object  x ,   String  name )   {          if   ( x  ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );      }      /**      * Sets the x-scale to be the default (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setXscale
()
 
{

        setXscale
(
DEFAULT_XMIN
,
 DEFAULT_XMAX
);

    
}

    
/**

     * Sets the y-scale to be the default (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setYscale
()
 
{

        setYscale
(
DEFAULT_YMIN
,
 DEFAULT_YMAX
);

    
}

    
/**

     * Sets the x-scale and y-scale to be the default

     * (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setScale
()
 
{

        setXscale
();

        setYscale
();

    
}

    
/**

     * Sets the x-scale to the specified range.

     *

     * 
@param
  min the minimum value of the x-scale

     * 
@param
  max the maximum value of the x-scale

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setXscale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            xmin 
=
 min 

 BORDER 
*
 size
;

            xmax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
/**

     * Sets the y-scale to the specified range.

     *

     * 
@param
  min the minimum value of the y-scale

     * 
@param
  max the maximum value of the y-scale

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setYscale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            ymin 
=
 min 

 BORDER 
*
 size
;

            ymax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
/**

     * Sets both the x-scale and y-scale to the (same) specified range.

     *

     * 
@param
  min the minimum value of the x– and y-scales

     * 
@param
  max the maximum value of the x– and y-scales

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setScale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            xmin 
=
 min 

 BORDER 
*
 size
;

            xmax 
=
 max 
+
 BORDER 
*
 size
;

            ymin 
=
 min 

 BORDER 
*
 size
;

            ymax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
// helper functions that scale from user coordinates to screen coordinates and back

    
private
 
static
 
double
  scaleX
(
double
 x
)
 
{
 
return
 width  
*
 
(


 xmin
)
 
/
 
(
xmax 

 xmin
);
 
}

    
private
 
static
 
double
  scaleY
(
double
 y
)
 
{
 
return
 height 
*
 
(
ymax 

 y
)
 
/
 
(
ymax 

 ymin
);
 
}

    
private
 
static
 
double
 factorX
(
double
 w
)
 
{
 
return
 w 
*
 width  
/
 
Math
.
abs
(
xmax 

 xmin
);
  
}

    
private
 
static
 
double
 factorY
(
double
 h
)
 
{
 
return
 h 
*
 height 
/
 
Math
.
abs
(
ymax 

 ymin
);
  
}

    
private
 
static
 
double
   userX
(
double
 x
)
 
{
 
return
 xmin 
+
 x 
*
 
(
xmax 

 xmin
)
 
/
 width
;
    
}

    
private
 
static
 
double
   userY
(
double
 y
)
 
{
 
return
 ymax 

 y 
*
 
(
ymax 

 ymin
)
 
/
 height
;
   
}

    
/**

     * Clears the screen to the default color (white).

     */

    
public
 
static
 
void
 clear
()
 
{

        clear
(
DEFAULT_CLEAR_COLOR
);

    
}

    
/**

     * Clears the screen to the specified color.

     *

     * 
@param
 color the color to make the background

     * 
@throws
 IllegalArgumentException if {
@code
 color} is {
@code
 null}

     */

    
public
 
static
 
void
 clear
(
Color
 color
)
 
{

        validateNotNull
(
color
,
 
“color”
);

        offscreen
.
setColor
(
color
);

        offscreen
.
fillRect
(
0
,
 
0
,
 width
,
 height
);

        offscreen
.
setColor
(
penColor
);

        draw
();

    
}

    
/**

     * Returns the current pen radius.

     *

     * 
@return
 the current value of the pen radius

     */

    
public
 
static
 
double
 getPenRadius
()
 
{

        
return
 penRadius
;

    
}

    
/**

     * Sets the pen size to the default size (0.002).

     * The pen is circular, so that lines have rounded ends, and when you set the

     * pen radius and draw a point, you get a circle of the specified radius.

     * The pen radius is not affected by coordinate scaling.

     */

    
public
 
static
 
void
 setPenRadius
()
 
{

        setPenRadius
(
DEFAULT_PEN_RADIUS
);

    
}

    
/**

     * Sets the radius of the pen to the specified size.

     * The pen is circular, so that lines have rounded ends, and when you set the

     * pen radius and draw a point, you get a circle of the specified radius.

     * The pen radius is not affected by coordinate scaling.

     *

     * 
@param
  radius the radius of the pen

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative, NaN, or infinite

     */

    
public
 
static
 
void
 setPenRadius
(
double
 radius
)
 
{

        validate
(
radius
,
 
“pen radius”
);

        validateNonnegative
(
radius
,
 
“pen radius”
);

        penRadius 
=
 radius
;

        float scaledPenRadius = (float) (radius * DEFAULT_SIZE);

        BasicStroke stroke = new BasicStroke(scaledPenRadius, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);

        // BasicStroke stroke = new BasicStroke(scaledPenRadius);        offscreen.setStroke(stroke);

    }

    /**     * Returns the current pen color.     *     * @return the current pen color     */

    public static Color getPenColor() {

        return penColor;

    }

    /**     * Sets the pen color to the default color (black).     */

    public static void setPenColor() {

        setPenColor(DEFAULT_PEN_COLOR);

    }

    /**     * Sets the pen color to the specified color.     * 

     * The predefined pen colors are     * {@code StdDraw.BLACK}, {@code StdDraw.BLUE}, {@code StdDraw.CYAN},     * {@code StdDraw.DARK_GRAY}, {@code StdDraw.GRAY}, {@code StdDraw.GREEN},     * {@code StdDraw.LIGHT_GRAY}, {@code StdDraw.MAGENTA}, {@code StdDraw.ORANGE},     * {@code StdDraw.PINK}, {@code StdDraw.RED}, {@code StdDraw.WHITE}, and     * {@code StdDraw.YELLOW}.     *     * @param color the color to make the pen     * @throws IllegalArgumentException if {@code color} is {@code null}     */

    public static void setPenColor(Color color) {

        validateNotNull(color, “color”);

        penColor = color;

        offscreen.setColor(penColor);

    }

    /**     * Sets the pen color to the specified RGB color.     *     * @param  red the amount of red (between 0 and 255)     * @param  green the amount of green (between 0 and 255)     * @param  blue the amount of blue (between 0 and 255)     * @throws IllegalArgumentException if {@code red}, {@code green},     *         or {@code blue} is outside its prescribed range     */

    public static void setPenColor(int red, int green, int blue) {

        if (red   < 0 || red   >= 256) throw new IllegalArgumentException(“red must be between 0 and 255”);

        if (green < 0 || green >= 256) throw new IllegalArgumentException(“green must be between 0 and 255”);

        if (blue  < 0 || blue  >= 256) throw new IllegalArgumentException(“blue must be between 0 and 255”);

        setPenColor(new Color(red, green, blue));

    }

    /**     * Returns the current font.     *     * @return the current font     */

    public static Font getFont() {

        return font;

    }

    /**     * Sets the font to the default font (sans serif, 16 point).     */

    public static void setFont() {

        setFont(DEFAULT_FONT);

    }

    /**     * Sets the font to the specified value.     *     * @param font the font     * @throws IllegalArgumentException if {@code font} is {@code null}     */

    public static void setFont(Font font) {

        validateNotNull(font, “font”);

        StdDraw.font = font;

    }

   /***************************************************************************    *  Drawing geometric shapes.    ***************************************************************************/

    /**     * Draws a line segment between (x0y0) and     * (x1y1).     *     * @param  x0 the x-coordinate of one endpoint     * @param  y0 the y-coordinate of one endpoint     * @param  x1 the x-coordinate of the other endpoint     * @param  y1 the y-coordinate of the other endpoint     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     */

    public static void line(double x0, double y0, double x1, double y1) {

        validate(x0, “x0”);

        validate(y0, “y0”);

        validate(x1, “x1”);

        validate(y1, “y1”);

        offscreen.draw(new Line2D.Double(scaleX(x0), scaleY(y0), scaleX(x1), scaleY(y1)));

        draw();

    }

    /**     * Draws one pixel at (xy).     * This method is private because pixels depend on the display.     * To achieve the same effect, set the pen radius to 0 and call {@code point()}.     *     * @param  x the x-coordinate of the pixel     * @param  y the y-coordinate of the pixel     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    private static void pixel(double x, double y) {

        validate(x, “x”);

        validate(y, “y”);

        offscreen.fillRect((int) Math.round(scaleX(x)), (int) Math.round(scaleY(y)), 1, 1);

    }

    /**     * Draws a point centered at (xy).     * The point is a filled circle whose radius is equal to the pen radius.     * To draw a single-pixel point, first set the pen radius to 0.     *     * @param x the x-coordinate of the point     * @param y the y-coordinate of the point     * @throws IllegalArgumentException if either {@code x} or {@code y} is either NaN or infinite     */

    public static void point(double x, double y) {

        validate(x, “x”);

        validate(y, “y”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double r = penRadius;

        float scaledPenRadius = (float) (r * DEFAULT_SIZE);

        // double ws = factorX(2*r);        // double hs = factorY(2*r);        // if (ws <= 1 && hs <= 1) pixel(x, y);        if (scaledPenRadius <= 1) pixel(x, y);         else offscreen.fill(new Ellipse2D.Double(xs - scaledPenRadius/2, ys - scaledPenRadius/2,                                                  scaledPenRadius, scaledPenRadius));         draw();     }     /**     * Draws a circle of the specified radius, centered at (xy).     *     * @param  x the x-coordinate of the center of the circle     * @param  y the y-coordinate of the center of the circle     * @param  radius the radius of the circle     * @throws IllegalArgumentException if {@code radius} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void circle(double x, double y, double radius) {

        validate(x, “x”);

        validate(y, “y”);

        validate(radius, “radius”);

        validateNonnegative(radius, “radius”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*radius);

        double hs = factorY(2*radius);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled circle of the specified radius, centered at (xy).     *     * @param  x the x-coordinate of the center of the circle     * @param  y the y-coordinate of the center of the circle     * @param  radius the radius of the circle     * @throws IllegalArgumentException if {@code radius} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledCircle(double x, double y, double radius) {

        validate(x, “x”);

        validate(y, “y”);

        validate(radius, “radius”);

        validateNonnegative(radius, “radius”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*radius);

        double hs = factorY(2*radius);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws an ellipse with the specified semimajor and semiminor axes,     * centered at (xy).     *     * @param  x the x-coordinate of the center of the ellipse     * @param  y the y-coordinate of the center of the ellipse     * @param  semiMajorAxis is the semimajor axis of the ellipse     * @param  semiMinorAxis is the semiminor axis of the ellipse     * @throws IllegalArgumentException if either {@code semiMajorAxis}     *         or {@code semiMinorAxis} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void ellipse(double x, double y, double semiMajorAxis, double semiMinorAxis) {

        validate(x, “x”);

        validate(y, “y”);

        validate(semiMajorAxis, “semimajor axis”);

        validate(semiMinorAxis, “semiminor axis”);

        validateNonnegative(semiMajorAxis, “semimajor axis”);

        validateNonnegative(semiMinorAxis, “semiminor axis”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*semiMajorAxis);

        double hs = factorY(2*semiMinorAxis);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled ellipse with the specified semimajor and semiminor axes,     * centered at (xy).     *     * @param  x the x-coordinate of the center of the ellipse     * @param  y the y-coordinate of the center of the ellipse     * @param  semiMajorAxis is the semimajor axis of the ellipse     * @param  semiMinorAxis is the semiminor axis of the ellipse     * @throws IllegalArgumentException if either {@code semiMajorAxis}     *         or {@code semiMinorAxis} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledEllipse(double x, double y, double semiMajorAxis, double semiMinorAxis) {

        validate(x, “x”);

        validate(y, “y”);

        validate(semiMajorAxis, “semimajor axis”);

        validate(semiMinorAxis, “semiminor axis”);

        validateNonnegative(semiMajorAxis, “semimajor axis”);

        validateNonnegative(semiMinorAxis, “semiminor axis”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*semiMajorAxis);

        double hs = factorY(2*semiMinorAxis);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Ellipse2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a circular arc of the specified radius,     * centered at (xy), from angle1 to angle2 (in degrees).     *     * @param  x the x-coordinate of the center of the circle     * @param  y the y-coordinate of the center of the circle     * @param  radius the radius of the circle     * @param  angle1 the starting angle. 0 would mean an arc beginning at 3 o’clock.     * @param  angle2 the angle at the end of the arc. For example, if     *         you want a 90 degree arc, then angle2 should be angle1 + 90.     * @throws IllegalArgumentException if {@code radius} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void arc(double x, double y, double radius, double angle1, double angle2) {

        validate(x, “x”);

        validate(y, “y”);

        validate(radius, “arc radius”);

        validate(angle1, “angle1”);

        validate(angle2, “angle2”);

        validateNonnegative(radius, “arc radius”);

        while (angle2 < angle1) angle2 += 360;         double xs = scaleX(x);         double ys = scaleY(y);         double ws = factorX(2*radius);         double hs = factorY(2*radius);         if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Arc2D.Double(xs - ws/2, ys - hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void square(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledSquare(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void rectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledRectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public static void polygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.draw(path);         draw();     }     /**     * Draws a filled polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public static void filledPolygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.fill(path);         draw();     }    /***************************************************************************    *  Drawing images.    ***************************************************************************/     // get an image from the given filename    private static Image getImage(String filename) {         if (filename == null) throw new IllegalArgumentException();         // to read from file        ImageIcon icon = new ImageIcon(filename);         // try to read from URL        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             try {                 URL url = new URL(filename);                 icon = new ImageIcon(url);             }             catch (MalformedURLException e) {                 /* not a url */             }         }         // in case file is inside a .jar (classpath relative to StdDraw)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource(filename);             if (url != null)                 icon = new ImageIcon(url);         }         // in case file is inside a .jar (classpath relative to root of jar)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource("/" + filename);             if (url == null) throw new IllegalArgumentException("image " + filename + " not found");             icon = new ImageIcon(url);         }         return icon.getImage();     }    /***************************************************************************    * [Summer 2016] Should we update to use ImageIO instead of ImageIcon()?    *               Seems to have some issues loading images on some systems    *               and slows things down on other systems.    *               especially if you don't call ImageIO.setUseCache(false)    *               One advantage is that it returns a BufferedImage.    ***************************************************************************/ /*    private static BufferedImage getImage(String filename) {        if (filename == null) throw new IllegalArgumentException();         // from a file or URL        try {            URL url = new URL(filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }         // in case file is inside a .jar (classpath relative to StdDraw)        try {            URL url = StdDraw.class.getResource(filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }         // in case file is inside a .jar (classpath relative to root of jar)        try {            URL url = StdDraw.class.getResource("/" + filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }        throw new IllegalArgumentException("image " + filename + " not found");    }*/     /**     * Draws the specified image centered at (xy).     * The supported image formats are JPEG, PNG, and GIF.     * As an optimization, the picture is cached, so there is no performance     * penalty for redrawing the same image multiple times (e.g., in an animation).     * However, if you change the picture file after drawing it, subsequent     * calls will draw the original picture.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if either {@code x} or {@code y} is either NaN or infinite     */

    public static void picture(double x, double y, String filename) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(filename, “filename”);

        // BufferedImage image = getImage(filename);        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = image.getWidth();    // can call only if image is a BufferedImage        // int hs = image.getHeight();        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         draw();     }     /**     * Draws the specified image centered at (xy),     * rotated given number of degrees.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x}, {@code y}, {@code degrees} is NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void picture(double x, double y, String filename, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        // BufferedImage image = getImage(filename);        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = image.getWidth();    // can call only if image is a BufferedImage        // int hs = image.getHeight();        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }     /**     * Draws the specified image centered at (xy),     * rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void picture(double x, double y, String filename, double scaledWidth, double scaledHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         else {             offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                        (int) Math.round(ys - hs/2.0),                                        (int) Math.round(ws),                                        (int) Math.round(hs), null);         }         draw();     }     /**     * Draws the specified image centered at (xy), rotated     * given number of degrees, and rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     */

    public static void picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                    (int) Math.round(ys - hs/2.0),                                    (int) Math.round(ws),                                    (int) Math.round(hs), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }    /***************************************************************************    *  Drawing text.    ***************************************************************************/     /**     * Writes the given text string in the current font, centered at (xy).     *     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void text(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws/2.0), (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, centered at (xy) and     * rotated by the specified number of degrees.     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x}, {@code y}, or {@code degrees} is either NaN or infinite     */

    public static void text(double x, double y, String text, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(text, “text”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        offscreen.rotate(Math.toRadians(-degrees), xs, ys);

        text(x, y, text);

        offscreen.rotate(Math.toRadians(+degrees), xs, ys);

    }

    /**     * Writes the given text string in the current font, left-aligned at (xy).     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void textLeft(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) xs, (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, right-aligned at (xy).     *     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void textRight(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws), (float) (ys + hs));

        draw();

    }

    /**     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds     * and enables double buffering.     * @param t number of milliseconds     * @deprecated replaced by {@link #enableDoubleBuffering()}, {@link #show()}, and {@link #pause(int t)}     */

    @Deprecated

    public static void show(int t) {

        validateNonnegative(t, “t”);

        show();

        pause(t);

        enableDoubleBuffering();

    }

    /**     * Pauses for t milliseconds. This method is intended to support computer animations.     * @param t number of milliseconds     */

    public static void pause(int t) {

        validateNonnegative(t, “t”);

        try {

            Thread.sleep(t);

        }

        catch (InterruptedException e) {

            System.out.println(“Error sleeping”);

        }

    }

    /**     * Copies offscreen buffer to onscreen buffer. There is no reason to call     * this method unless double buffering is enabled.     */

    public static void show() {

        onscreen.drawImage(offscreenImage, 0, 0, null);

        frame.repaint();

    }

    // draw onscreen if defer is false    private static void draw() {

        if (!defer) show();

    }

    /**     * Enables double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be deferred until the next call     * to show(). Useful for animations.     */

    public static void enableDoubleBuffering() {

        defer = true;

    }

    /**     * Disables double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be displayed on screen when called.     * This is the default.     */

    public static void disableDoubleBuffering() {

        defer = false;

    }

   /***************************************************************************    *  Save drawing to a file.    ***************************************************************************/

    /**     * Saves the drawing to using the specified filename.     * The supported image formats are JPEG and PNG;     * the filename suffix must be {@code  } or {@code  }.     *     * @param  filename the name of the file with one of the required suffixes     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void save(String filename) {

        validateNotNull(filename, “filename”);

        File file = new File(filename);

        String suffix = filename.substring(filename.lastIndexOf(‘.’) + 1);

        // png files        if (“png”.equalsIgnoreCase(suffix)) {

            try {

                ImageIO.write(onscreenImage, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        // need to change from ARGB to RGB for JPEG        // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727        else if (“jpg”.equalsIgnoreCase(suffix)) {

            WritableRaster raster = onscreenImage.getRaster();

            WritableRaster newRaster;

            newRaster = raster.createWritableChild(0, 0, width, height, 0, 0, new int[] {0, 1, 2});

            DirectColorModel cm = (DirectColorModel) onscreenImage.getColorModel();

            DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(),

                                                          cm.getRedMask(),

                                                          cm.getGreenMask(),

                                                          cm.getBlueMask());

            BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false,  null);

            try {

                ImageIO.write(rgbBuffer, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        else {

            System.out.println(“Invalid image file type: ” + suffix);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void actionPerformed(ActionEvent e) {

        FileDialog chooser = new FileDialog(StdDraw.frame, “Use a   or   extension”, FileDialog.SAVE);

        chooser.setVisible(true);

        String filename = chooser.getFile();

        if (filename != null) {

            StdDraw.save(chooser.getDirectory() + File.separator + chooser.getFile());

        }

    }

   /***************************************************************************    *  Mouse interactions.    ***************************************************************************/

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed; {@code false} otherwise     */

    public static boolean isMousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed; {@code false} otherwise     * @deprecated replaced by {@link #isMousePressed()}     */

    @Deprecated

    public static boolean mousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns the x-coordinate of the mouse.     *     * @return the x-coordinate of the mouse     */

    public static double mouseX() {

        synchronized (mouseLock) {

            return mouseX;

        }

    }

    /**     * Returns the y-coordinate of the mouse.     *     * @return y-coordinate of the mouse     */

    public static double mouseY() {

        synchronized (mouseLock) {

            return mouseY;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseClicked(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseEntered(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseExited(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mousePressed(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

            isMousePressed = true;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseReleased(MouseEvent e) {

        synchronized (mouseLock) {

            isMousePressed = false;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseDragged(MouseEvent e)  {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseMoved(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

        }

    }

   /***************************************************************************    *  Keyboard interactions.    ***************************************************************************/

    /**     * Returns true if the user has typed a key (that has not yet been processed).     *     * @return {@code true} if the user has typed a key (that has not yet been processed     *         by {@link #nextKeyTyped()}; {@code false} otherwise     */

    public static boolean hasNextKeyTyped() {

        synchronized (keyLock) {

            return !keysTyped.isEmpty();

        }

    }

    /**     * Returns the next key that was typed by the user (that your program has not already processed).     * This method should be preceded by a call to {@link #hasNextKeyTyped()} to ensure     * that there is a next key to process.     * This method returns a Unicode character corresponding to the key     * typed (such as {@code ‘a’} or {@code ‘A’}).     * It cannot identify action keys (such as F1 and arrow keys)     * or modifier keys (such as control).     *     * @return the next key typed by the user (that your program has not already processed).     * @throws NoSuchElementException if there is no remaining key     */

    public static char nextKeyTyped() {

        synchronized (keyLock) {

            if (keysTyped.isEmpty()) {

                throw new NoSuchElementException(“your program has already processed all keystrokes”);

            }

            return keysTyped.remove(keysTyped.size() – 1);

            // return keysTyped.removeLast();        }

    }

    /**     * Returns true if the given key is being pressed.     * 

     * This method takes the keycode (corresponding to a physical key)    *  as an argument. It can handle action keys     * (such as F1 and arrow keys) and modifier keys (such as shift and control).     * See {@link KeyEvent} for a description of key codes.     *     * @param  keycode the key to check if it is being pressed     * @return {@code true} if {@code keycode} is currently being pressed;     *         {@code false} otherwise     */

    public static boolean isKeyPressed(int keycode) {

        synchronized (keyLock) {

            return keysDown.contains(keycode);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyTyped(KeyEvent e) {

        synchronized (keyLock) {

            keysTyped.addFirst(e.getKeyChar());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyPressed(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.add(e.getKeyCode());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyReleased(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.remove(e.getKeyCode());

        }

    }

   /***************************************************************************    *  For improved resolution on Mac Retina displays.    ***************************************************************************/

    private static class RetinaImageIcon extends ImageIcon {

            public RetinaImageIcon(Image image) {

            super(image);

        }

        public int getIconWidth() {

            return super.getIconWidth() / 2;

        }

        /**         * Gets the height of the icon.         *         * @return the height in pixels of this icon         */

        public int getIconHeight() {

            return super.getIconHeight() / 2;

        }

        public synchronized void paintIcon(Component c, Graphics g, int x, int y) {

            Graphics2D g2 = (Graphics2D) g.create();

            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);

            g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

            g2.scale(0.5, 0.5);

            super.paintIcon(c, g2, x * 2, y * 2);

            g2.dispose();

        }

    }

    /**     * Test client.     *     * @param args the command-line arguments     */

    public static void main(String[] args) {

        StdDraw.square(0.2, 0.8, 0.1);

        StdDraw.filledSquare(0.8, 0.8, 0.2);

        StdDraw.circle(0.8, 0.2, 0.2);

        StdDraw.setPenColor(StdDraw.BOOK_RED);

        StdDraw.setPenRadius(0.02);

        StdDraw.arc(0.8, 0.2, 0.1, 200, 45);

        // draw a blue diamond        StdDraw.setPenRadius();

        StdDraw.setPenColor(StdDraw.BOOK_BLUE);

        double[] x = { 0.1, 0.2, 0.3, 0.2 };

        double[] y = { 0.2, 0.3, 0.2, 0.1 };

        StdDraw.filledPolygon(x, y);

        // text        StdDraw.setPenColor(StdDraw.BLACK);

        StdDraw.text(0.2, 0.5, “black text”);

        StdDraw.setPenColor(StdDraw.WHITE);

        StdDraw.text(0.8, 0.8, “white text”);

    }

}

/****************************************************************************** *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. * *  This file is part of algs4.jar, which accompanies the textbook * *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. *      http://algs4.cs.princeton.edu * * *  algs4.jar is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  algs4.jar is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with algs4.jar.  If not, see http://www.gnu.org/licenses. ******************************************************************************/

edu/princeton/cs/algs4/StdIn.java
edu/princeton/cs/algs4/StdIn.java
/******************************************************************************

 *  Compilation:  javac StdIn.java

 *  Execution:    java StdIn   (interactive test of basic functionality)

 *  Dependencies: none

 *

 *  Reads in data of various types from standard input.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
ArrayList
;

import
 java
.
util
.
InputMismatchException
;

import
 java
.
util
.
Locale
;

import
 java
.
util
.
NoSuchElementException
;

import
 java
.
util
.
Scanner
;

import
 java
.
util
.
regex
.
Pattern
;

/**

 *  The {
@code
 StdIn} class provides static methods for reading strings

 *  and numbers from standard input.

 *  These functions fall into one of four categories:

 *  

     *  

  • those for reading individual tokens from standard input, one at a time,

     *      and converting each to a number, string, or boolean

     *  

  • those for reading characters from standard input, one at a time

     *  

  • those for reading lines from standard input, one at a time

     *  

  • those for reading a sequence of values of the same type from standard input,

     *      and returning the values in an array

     *  

 *  

 *  Generally, it is best not to mix functions from the different

 *  categories in the same program.

 *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdIn.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdIn.java

 *  and put a copy in your working directory.

 *  

 *  Reading tokens from standard input and converting to numbers and strings.

 *  You can use the following methods to read numbers, strings, and booleans

 *  from standard input one at a time:

 *  

     *  

  •  {
    @link
     #isEmpty()}

     *  

  •  {
    @link
     #readInt()}

     *  

  •  {
    @link
     #readDouble()}

     *  

  •  {
    @link
     #readString()}

     *  

  •  {
    @link
     #readShort()}

     *  

  •  {
    @link
     #readLong()}

     *  

  •  {
    @link
     #readFloat()}

     *  

  •  {
    @link
     #readByte()}

     *  

  •  {
    @link
     #readBoolean()}

     *  

 *  

 *  The first method returns true if standard input has no more tokens.

 *  Each other method skips over any input that is whitespace. Then, it reads

 *  the next token and attempts to convert it into a value of the specified

 *  type. If it succeeds, it returns that value; otherwise, it

 *  throws an {
@link
 InputMismatchException}.

 *  

 *  Whitespace includes spaces, tabs, and newlines; the full definition

 *  is inherited from {
@link
 Character#isWhitespace(char)}.

 *  A token is a maximal sequence of non-whitespace characters.

 *  The precise rules for describing which tokens can be converted to

 *  integers and floating-point numbers are inherited from

 *  Scanner,

 *  using the locale {
@link
 Locale#US}; the rules

 *  for floating-point numbers are slightly different

 *  from those in {
@link
 Double#valueOf(String)},

 *  but unlikely to be of concern to most programmers.

 *  

 *  As an example, the following code fragment reads integers from standard input,

 *  one at a time, and prints them one per line.

 *  


 *  while (!StdIn.isEmpty()) {

 *      double value = StdIn.readDouble();

 *      StdOut.println(value);

 *  }

 *  

 *  

 *  Reading characters from standard input.

 *  You can use the following two methods to read characters from standard input one at a time:

 *  

     *  

  •  {
    @link
     #hasNextChar()}

     *  

  •  {
    @link
     #readChar()}

     *  

 *  

 *  The first method returns true if standard input has more input (including whitespace).

 *  The second method reads and returns the next character of input on standard 

 *  input (possibly a whitespace character).

 *  

 *  As an example, the following code fragment reads characters from standard input,

 *  one character at a time, and prints it to standard output.

 *  


 *  while (StdIn.hasNextChar()) {

 *      char c = StdIn.readChar();

 *      StdOut.print(c);

 *  }

 *  

 *  

 *  Reading lines from standard input.

 *  You can use the following two methods to read lines from standard input:

 *  

     *  

  •  {
    @link
     #hasNextLine()}

     *  

  •  {
    @link
     #readLine()}

     *  

 *  

 *  The first method returns true if standard input has more input (including whitespace).

 *  The second method reads and returns the remaining portion of 

 *  the next line of input on standard input (possibly whitespace),

 *  discarding the trailing line separator.

 *  

 *  A line separator is defined to be one of the following strings:

 *  {
@code
 \n} (Linux), {
@code
 \r} (old Macintosh),

 *  {
@code
 \r\n} (Windows),

 *  {
@code
 \}{
@code
 u2028}, {
@code
 \}{
@code
 u2029}, or {
@code
 \}{
@code
 u0085}.

 *  

 *  As an example, the following code fragment reads text from standard input,

 *  one line at a time, and prints it to standard output.

 *  


 *  while (StdIn.hasNextLine()) {

 *      String line = StdIn.readLine();

 *      StdOut.println(line);

 *  }

 *  

 *  

 *  Reading a sequence of values of the same type from standard input.

 *  You can use the following methods to read a sequence numbers, strings,

 *  or booleans (all of the same type) from standard input:

 *  

     *  

  •  {
    @link
     #readAllDoubles()}

     *  

  •  {
    @link
     #readAllInts()}

     *  

  •  {
    @link
     #readAllLongs()}

     *  

  •  {
    @link
     #readAllStrings()}

     *  

  •  {
    @link
     #readAllLines()}

     *  

  •  {
    @link
     #readAll()}

     *  

 *  

 *  The first three methods read of all of remaining token on standard input

 *  and converts the tokens to values of

 *  the specified type, as in the corresponding

 *  {
@code
 readDouble}, {
@code
 readInt}, and {
@code
 readString()} methods.

 *  The {
@code
 readAllLines()} method reads all remaining lines on standard

 *  input and returns them as an array of strings.

 *  The {
@code
 readAll()} method reads all remaining input on standard

 *  input and returns it as a string.

 *  

 *  As an example, the following code fragment reads all of the remaining

 *  tokens from standard input and returns them as an array of strings.

 *  


 *  String[] words = StdIn.readAllStrings();

 *  

 *  

 *  Differences with Scanner.

 *  {
@code
 StdIn} and {
@link
 Scanner} are both designed to parse 

 *  tokens and convert them to primitive types and strings.

 *  The main differences are summarized below:

 *  

     *  

  •  {
    @code
     StdIn} is a set of static methods and reads 

     *       reads input from only standard input. It is suitable for use before

     *       a programmer knows about objects.

     *       See {
    @link
     In} for an object-oriented version that handles

     *       input from files, URLs,

     *       and sockets.

     *  

  •  {
    @code
     StdIn} uses whitespace as the delimiter pattern

     *       that separates tokens.

     *       {
    @link
     Scanner} supports arbitrary delimiter patterns.

     *  

  •  {
    @code
     StdIn} coerces the character-set encoding to UTF-8,

     *       which is the most widely used character encoding for Unicode.

     *  

  •  {
    @code
     StdIn} coerces the locale to {
    @link
     Locale#US},

     *       for consistency with {
    @link
     StdOut}, {
    @link
     Double#parseDouble(String)},

     *       and floating-point literals.

     *  

  •  {
    @code
     StdIn} has convenient methods for reading a single

     *       character; reading in sequences of integers, doubles, or strings;

     *       and reading in all of the remaining input.

     *  

 *  

 *  Historical note: {
@code
 StdIn} preceded {
@code
 Scanner}; when

 *  {
@code
 Scanner} was introduced, this class was re-implemented to use {
@code
 Scanner}.

 *  

 *  Using standard input.

 *  Standard input is a fundamental operating system abstraction on Mac OS X,

 *  Windows, and Linux.

 *  The methods in {
@code
 StdIn} are blocking, which means that they

 *  will wait until you enter input on standard input.

 *  If your program has a loop that repeats until standard input is empty,

 *  you must signal that the input is finished.

 *  To do so, depending on your operating system and IDE, 

 *  use either {
@code
 } or {
@code
 }, on its own line.

 *  If you are redirecting standard input from a file, you will not need

 *  to do anything to signal that the input is finished.

 *  

 *  Known bugs.

 *  Java’s UTF-8 encoding does not recognize the optional 

 *  byte-order mask.

 *  If the input begins with the optional byte-order mask, {
@code
 StdIn}

 *  will have an extra character {
@code
 \}{
@code
 uFEFF} at the beginning.

 *  

 *  Reference. 

 *  For additional documentation,

 *  see Section 1.5 of   

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 David Pritchard

 */

public
 
final
 
class
 
StdIn
 
{

    
/*** begin: section (1 of 2) of code duplicated from In to StdIn. */

    

    
// assume Unicode UTF-8 encoding

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with System.out.

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// the default token separator; we maintain the invariant that this value

    
// is held by the scanner’s delimiter between calls

    
private
 
static
 
final
 
Pattern
 WHITESPACE_PATTERN 
=
 
Pattern
.
compile
(
“\\p{javaWhitespace}+”
);

    
// makes whitespace significant

    
private
 
static
 
final
 
Pattern
 EMPTY_PATTERN 
=
 
Pattern
.
compile
(
“”
);

    
// used to read the entire input

    
private
 
static
 
final
 
Pattern
 EVERYTHING_PATTERN 
=
 
Pattern
.
compile
(
“\\A”
);

    
/*** end: section (1 of 2) of code duplicated from In to StdIn. */

    
private
 
static
 
Scanner
 scanner
;

 

    
// it doesn’t make sense to instantiate this class

    
private
 
StdIn
()
 
{
 
}

    
//// begin: section (2 of 2) of code duplicated from In to StdIn,

    
//// with all methods changed from “public” to “public static”

   
/**

     * Returns true if standard input is empty (except possibly for whitespace).

     * Use this method to know whether the next call to {
@link
 #readString()}, 

     * {
@link
 #readDouble()}, etc will succeed.

     *

     * 
@return
 {
@code
 true} if standard input is empty (except possibly

     *         for whitespace); {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 isEmpty
()
 
{

        
return
 
!
scanner
.
hasNext
();

    
}

   
/**

     * Returns true if standard input has a next line.

     * Use this method to know whether the

     * next call to {
@link
 #readLine()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextChar()}.

     *

     * 
@return
 {
@code
 true} if standard input has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 hasNextLine
()
 
{

        
return
 scanner
.
hasNextLine
();

    
}

    
/**

     * Returns true if standard input has more input (including whitespace).

     * Use this method to know whether the next call to {
@link
 #readChar()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextLine()}.

     *

     * 
@return
 {
@code
 true} if standard input has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 hasNextChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
boolean
 result 
=
 scanner
.
hasNext
();

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

        
return
 result
;

    
}

   
/**

     * Reads and returns the next line, excluding the line separator if present.

     *

     * 
@return
 the next line, excluding the line separator if present;

     *         {
@code
 null} if no such line

     */

    
public
 
static
 
String
 readLine
()
 
{

        
String
 line
;

        
try
 
{

            line 
=
 scanner
.
nextLine
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            line 
=
 
null
;

        
}

        
return
 line
;

    
}

    
/**

     * Reads and returns the next character.

     *

     * 
@return
 the next {
@code
 char}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
char
 readChar
()
 
{

        
try
 
{

            scanner
.
useDelimiter
(
EMPTY_PATTERN
);

            
String
 ch 
=
 scanner
.
next
();

            
assert
 ch
.
length
()
 
==
 
1
 
:
 
“Internal (Std)In.readChar() error!”

                
+
 
” Please contact the authors.”
;

            scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

            
return
 ch
.
charAt
(
0
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘char’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}
  

   
/**

     * Reads and returns the remainder of the input, as a string.

     *

     * 
@return
 the remainder of the input, as a string

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
String
 readAll
()
 
{

        
if
 
(
!
scanner
.
hasNextLine
())

            
return
 
“”
;

        
String
 result 
=
 scanner
.
useDelimiter
(
EVERYTHING_PATTERN
).
next
();

        
// not that important to reset delimeter, since now scanner is empty

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);
 
// but let’s do it anyway

        
return
 result
;

    
}

   
/**

     * Reads the next token  and returns the {
@code
 String}.

     *

     * 
@return
 the next {
@code
 String}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
String
 readString
()
 
{

        
try
 
{

            
return
 scanner
.
next
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘String’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as an integer, and returns the integer.

     *

     * 
@return
 the next integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as an {
@code
 int}

     */

    
public
 
static
 
int
 readInt
()
 
{

        
try
 
{

            
return
 scanner
.
nextInt
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read an ‘int’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read an ‘int’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a double, and returns the double.

     *

     * 
@return
 the next double on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 double}

     */

    
public
 
static
 
double
 readDouble
()
 
{

        
try
 
{

            
return
 scanner
.
nextDouble
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘double’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘double’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a float, and returns the float.

     *

     * 
@return
 the next float on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 float}

     */

    
public
 
static
 
float
 readFloat
()
 
{

        
try
 
{

            
return
 scanner
.
nextFloat
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘float’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘float’ value from standard input, ”

                                           
+
 
“but there no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a long integer, and returns the long integer.

     *

     * 
@return
 the next long integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 long}

     */

    
public
 
static
 
long
 readLong
()
 
{

        
try
 
{

            
return
 scanner
.
nextLong
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘long’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘long’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a short integer, and returns the short integer.

     *

     * 
@return
 the next short integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 short}

     */

    
public
 
static
 
short
 readShort
()
 
{

        
try
 
{

            
return
 scanner
.
nextShort
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘short’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘short’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a byte, and returns the byte.

     *

     * 
@return
 the next byte on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 byte}

     */

    
public
 
static
 
byte
 readByte
()
 
{

        
try
 
{

            
return
 scanner
.
nextByte
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘byte’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘byte’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads the next token from standard input, parses it as a boolean,

     * and returns the boolean.

     *

     * 
@return
 the next boolean on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 boolean}:

     *    {
@code
 true} or {
@code
 1} for true, and {
@code
 false} or {
@code
 0} for false,

     *    ignoring case

     */

    
public
 
static
 
boolean
 readBoolean
()
 
{

        
try
 
{

            
String
 token 
=
 readString
();

            
if
 
(
“true”
.
equalsIgnoreCase
(
token
))
  
return
 
true
;

            
if
 
(
“false”
.
equalsIgnoreCase
(
token
))
 
return
 
false
;

            
if
 
(
“1”
.
equals
(
token
))
               
return
 
true
;

            
if
 
(
“0”
.
equals
(
token
))
               
return
 
false
;

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘boolean’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘boolean’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads all remaining tokens from standard input and returns them as an array of strings.

     *

     * 
@return
 all remaining tokens on standard input, as an array of strings

     */

    
public
 
static
 
String
[]
 readAllStrings
()
 
{

        
// we could use readAll.trim().split(), but that’s not consistent

        
// because trim() uses characters 0x00..0x20 as whitespace

        
String
[]
 tokens 
=
 WHITESPACE_PATTERN
.
split
(
readAll
());

        
if
 
(
tokens
.
length 
==
 
0
 
||
 tokens
[
0
].
length
()
 
>
 
0
)

            
return
 tokens
;

        
// don’t include first token if it is leading whitespace

        
String
[]
 decapitokens 
=
 
new
 
String
[
tokens
.
length

1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  tokens . length  -   1 ;  i ++ )             decapitokens [ i ]   =  tokens [ i + 1 ];          return  decapitokens ;      }      /**      * Reads all remaining lines from standard input and returns them as an array of strings.      *  @return  all remaining lines on standard input, as an array of strings      */      public   static   String []  readAllLines ()   {          ArrayList < String >
 lines 
=
 
new
 
ArrayList
< String >
();

        
while
 
(
hasNextLine
())
 
{

            lines
.
add
(
readLine
());

        
}

        
return
 lines
.
toArray
(
new
 
String
[
lines
.
size
()]);

    
}

    
/**

     * Reads all remaining tokens from standard input, parses them as integers, and returns

     * them as an array of integers.

     * 
@return
 all remaining integers on standard input, as an array

     * 
@throws
 InputMismatchException if any token cannot be parsed as an {
@code
 int}

     */

    
public
 
static
 
int
[]
 readAllInts
()
 
{

        
String
[]
 fields 
=
 readAllStrings
();

        
int
[]
 vals 
=
 
new
 
int
[
fields
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  fields . length ;  i ++ )             vals [ i ]   =   Integer . parseInt ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from standard input, parses them as longs, and returns      * them as an array of longs.      *  @return  all remaining longs on standard input, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  long}      */      public   static   long []  readAllLongs ()   {          String []  fields  =  readAllStrings ();          long []  vals  =   new   long [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Long . parseLong ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from standard input, parses them as doubles, and returns      * them as an array of doubles.      *  @return  all remaining doubles on standard input, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}      */      public   static   double []  readAllDoubles ()   {          String []  fields  =  readAllStrings ();          double []  vals  =   new   double [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Double . parseDouble ( fields [ i ]);          return  vals ;      }           //// end: section (2 of 2) of code duplicated from In to StdIn                // do this once when StdIn is initialized      static   {         resync ();      }      /**      * If StdIn changes, use this to reinitialize the scanner.      */      private   static   void  resync ()   {         setScanner ( new   Scanner ( new  java . io . BufferedInputStream ( System . in ),  CHARSET_NAME ));      }           private   static   void  setScanner ( Scanner  scanner )   {          StdIn . scanner  =  scanner ;          StdIn . scanner . useLocale ( LOCALE );      }     /**      * Reads all remaining tokens, parses them as integers, and returns      * them as an array of integers.      *  @return  all remaining integers, as an array      *  @throws  InputMismatchException if any token cannot be parsed as an { @code  int}      *  @deprecated  Replaced by { @link  #readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ()   {          return  readAllInts ();      }     /**      * Reads all remaining tokens, parses them as doubles, and returns      * them as an array of doubles.      *  @return  all remaining doubles, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}      *  @deprecated  Replaced by { @link  #readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ()   {          return  readAllDoubles ();      }     /**      * Reads all remaining tokens and returns them as an array of strings.      *  @return  all remaining tokens, as an array of strings      *  @deprecated  Replaced by { @link  #readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ()   {          return  readAllStrings ();      }      /**      * Interactive test of basic functionality.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          StdOut . print ( "Type a string: " );          String  s  =   StdIn . readString ();          StdOut . println ( "Your string was: "   +  s );          StdOut . println ();          StdOut . print ( "Type an int: " );          int  a  =   StdIn . readInt ();          StdOut . println ( "Your int was: "   +  a );          StdOut . println ();          StdOut . print ( "Type a boolean: " );          boolean  b  =   StdIn . readBoolean ();          StdOut . println ( "Your boolean was: "   +  b );          StdOut . println ();          StdOut . print ( "Type a double: " );          double  c  =   StdIn . readDouble ();          StdOut . println ( "Your double was: "   +  c );          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/StdOut.java edu/princeton/cs/algs4/StdOut.java /******************************************************************************  *  Compilation:  javac StdOut.java  *  Execution:    java StdOut  *  Dependencies: none  *  *  Writes data of various types to standard output.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . io . OutputStreamWriter ; import  java . io . PrintWriter ; import  java . io . UnsupportedEncodingException ; import  java . util . Locale ; /**  *  This class provides methods for printing strings and numbers to standard output.  *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdOut.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdOut.java

 *  and put a copy in your working directory.

 *  

 *  Here is an example program that uses {
@code
 StdOut}:

 *  


 *   public class TestStdOut {

 *       public static void main(String[] args) {

 *           int a = 17;

 *           int b = 23;

 *           int sum = a + b;

 *           StdOut.println("Hello, World");

 *           StdOut.printf("%d + %d = %d\n", a, b, sum);

 *       }

 *   }

 *  

 *  

 *  Differences with System.out.

 *  The behavior of {
@code
 StdOut} is similar to that of {
@link
 System#out},

 *  but there are a few technical differences:

 *  

     *  

  •  {
    @code
     StdOut} coerces the character-set encoding to UTF-8,

     *       which is a standard character encoding for Unicode.

     *  

  •  {
    @code
     StdOut} coerces the locale to {
    @link
     Locale#US},

     *       for consistency with {
    @link
     StdIn}, {
    @link
     Double#parseDouble(String)},

     *       and floating-point literals.

     *  

  •  {
    @code
     StdOut} flushes standard output after each call to

     *       {
    @code
     print()} so that text will appear immediately in the terminal.

     *  

 *  

 *  Reference.

 *  For additional documentation,

 *  see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdOut
 
{

    
// force Unicode UTF-8 encoding; otherwise it’s system dependent

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with StdIn

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// send output here

    
private
 
static
 
PrintWriter
 out
;

    
// this is called before invoking any methods

    
static
 
{

        
try
 
{

            out 
=
 
new
 
PrintWriter
(
new
 
OutputStreamWriter
(
System
.
out
,
 CHARSET_NAME
),
 
true
);

        
}

        
catch
 
(
UnsupportedEncodingException
 e
)
 
{

            
System
.
out
.
println
(
e
);

        
}

    
}

    
// don’t instantiate

    
private
 
StdOut
()
 
{
 
}

   
/**

     * Terminates the current line by printing the line-separator string.

     */

    
public
 
static
 
void
 println
()
 
{

        out
.
println
();

    
}

   
/**

     * Prints an object to this output stream and then terminates the line.

     *

     * 
@param
 x the object to print

     */

    
public
 
static
 
void
 println
(
Object
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a boolean to standard output and then terminates the line.

     *

     * 
@param
 x the boolean to print

     */

    
public
 
static
 
void
 println
(
boolean
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a character to standard output and then terminates the line.

     *

     * 
@param
 x the character to print

     */

    
public
 
static
 
void
 println
(
char
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a double to standard output and then terminates the line.

     *

     * 
@param
 x the double to print

     */

    
public
 
static
 
void
 println
(
double
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to standard output and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 println
(
float
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to standard output and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 println
(
int
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a long to standard output and then terminates the line.

     *

     * 
@param
 x the long to print

     */

    
public
 
static
 
void
 println
(
long
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a short integer to standard output and then terminates the line.

     *

     * 
@param
 x the short to print

     */

    
public
 
static
 
void
 println
(
short
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a byte to standard output and then terminates the line.

     * 

     * To write binary data, see {
@link
 BinaryStdOut}.

     *

     * 
@param
 x the byte to print

     */

    
public
 
static
 
void
 println
(
byte
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Flushes standard output.

     */

    
public
 
static
 
void
 print
()
 
{

        out
.
flush
();

    
}

   
/**

     * Prints an object to standard output and flushes standard output.

     * 

     * 
@param
 x the object to print

     */

    
public
 
static
 
void
 print
(
Object
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a boolean to standard output and flushes standard output.

     * 

     * 
@param
 x the boolean to print

     */

    
public
 
static
 
void
 print
(
boolean
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a character to standard output and flushes standard output.

     * 

     * 
@param
 x the character to print

     */

    
public
 
static
 
void
 print
(
char
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a double to standard output and flushes standard output.

     * 

     * 
@param
 x the double to print

     */

    
public
 
static
 
void
 print
(
double
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a float to standard output and flushes standard output.

     * 

     * 
@param
 x the float to print

     */

    
public
 
static
 
void
 print
(
float
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints an integer to standard output and flushes standard output.

     * 

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 print
(
int
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a long integer to standard output and flushes standard output.

     * 

     * 
@param
 x the long integer to print

     */

    
public
 
static
 
void
 print
(
long
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a short integer to standard output and flushes standard output.

     * 

     * 
@param
 x the short integer to print

     */

    
public
 
static
 
void
 print
(
short
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a byte to standard output and flushes standard output.

     *

     * 
@param
 x the byte to print

     */

    
public
 
static
 
void
 print
(
byte
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to standard output, using the specified format

     * string and arguments, and then flushes standard output.

     *

     *

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
static
 
void
 printf
(
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
LOCALE
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to standard output, using the locale and

     * the specified format string and arguments; then flushes standard output.

     *

     * 
@param
 locale the locale

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
static
 
void
 printf
(
Locale
 locale
,
 
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
locale
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Unit tests some of the methods in {
@code
 StdOut}.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// write to stdout

        
StdOut
.
println
(
“Test”
);

        
StdOut
.
println
(
17
);

        
StdOut
.
println
(
true
);

        
StdOut
.
printf
(
“%.6f\n”
,
 
1.0
/
7.0
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/StdRandom.java
edu/princeton/cs/algs4/StdRandom.java
/******************************************************************************

 *  Compilation:  javac StdRandom.java

 *  Execution:    java StdRandom

 *  Dependencies: StdOut.java

 *

 *  A library of static methods to generate pseudo-random numbers from

 *  different distributions (bernoulli, uniform, gaussian, discrete,

 *  and exponential). Also includes a method for shuffling an array.

 *

 *

 *  %  java StdRandom 5

 *  seed = 1316600602069

 *  59 16.81826  true 8.83954  0 

 *  32 91.32098  true 9.11026  0 

 *  35 10.11874  true 8.95396  3 

 *  92 32.88401  true 8.87089  0 

 *  72 92.55791  true 9.46241  0 

 *

 *  % java StdRandom 5

 *  seed = 1316600616575

 *  96 60.17070  true 8.72821  0 

 *  79 32.01607  true 8.58159  0 

 *  81 59.49065  true 9.10423  1 

 *  96 51.65818  true 9.02102  0 

 *  99 17.55771  true 8.99762  0 

 *

 *  % java StdRandom 5 1316600616575

 *  seed = 1316600616575

 *  96 60.17070  true 8.72821  0 

 *  79 32.01607  true 8.58159  0 

 *  81 59.49065  true 9.10423  1 

 *  96 51.65818  true 9.02102  0 

 *  99 17.55771  true 8.99762  0 

 *

 *

 *  Remark

 *  ——

 *    – Relies on randomness of nextDouble() method in java.util.Random

 *      to generate pseudo-random numbers in [0, 1).

 *

 *    – This library allows you to set and get the pseudo-random number seed.

 *

 *    – See http://www.honeylocust.com/RngPack/ for an industrial

 *      strength random number generator in Java.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
util
.
Random
;

/**

 *  The {
@code
 StdRandom} class provides static methods for generating

 *  random number from various discrete and continuous distributions, 

 *  including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto,

 *  Poisson, and Cauchy. It also provides method for shuffling an

 *  array or subarray and generating random permutations.

 *  

 *  By convention, all intervals are half open. For example,

 *  uniform(-1.0, 1.0) returns a random number between

 *  -1.0 (inclusive) and 1.0 (exclusive).

 *  Similarly, shuffle(a, lo, hi) shuffles the hi - lo

 *  elements in the array a[], starting at index lo

 *  (inclusive) and ending at index hi (exclusive).

 *  

 *  For additional documentation,

 *  see Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdRandom
 
{

    
private
 
static
 
Random
 random
;
    
// pseudo-random number generator

    
private
 
static
 
long
 seed
;
        
// pseudo-random number generator seed

    
// static initializer

    
static
 
{

        
// this is how the seed was set in Java 1.4

        seed 
=
 
System
.
currentTimeMillis
();

        random 
=
 
new
 
Random
(
seed
);

    
}

    
// don’t instantiate

    
private
 
StdRandom
()
 
{
 
}

    
/**

     * Sets the seed of the pseudo-random number generator.

     * This method enables you to produce the same sequence of “random”

     * number for each execution of the program.

     * Ordinarily, you should call this method at most once per program.

     *

     * 
@param
 s the seed

     */

    
public
 
static
 
void
 setSeed
(
long
 s
)
 
{

        seed   
=
 s
;

        random 
=
 
new
 
Random
(
seed
);

    
}

    
/**

     * Returns the seed of the pseudo-random number generator.

     *

     * 
@return
 the seed

     */

    
public
 
static
 
long
 getSeed
()
 
{

        
return
 seed
;

    
}

    
/**

     * Returns a random real number uniformly in [0, 1).

     *

     * 
@return
 a random real number uniformly in [0, 1)

     */

    
public
 
static
 
double
 uniform
()
 
{

        
return
 random
.
nextDouble
();

    
}

    
/**

     * Returns a random integer uniformly in [0, n).

     * 

     * 
@param
 n number of possible integers

     * 
@return
 a random integer uniformly between 0 (inclusive) and {
@code
 n} (exclusive)

     * 
@throws
 IllegalArgumentException if {
@code
 n <= 0}      */      public   static   int  uniform ( int  n )   {          if   ( n  <=   0 )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );          return  random . nextInt ( n );      }      /**      * Returns a random long integer uniformly in [0, n).      *       *  @param  n number of possible { @code  long} integers      *  @return  a random long integer uniformly between 0 (inclusive) and { @code  n} (exclusive)      *  @throws  IllegalArgumentException if { @code  n <= 0}      */      public   static   long  uniform ( long  n )   {          if   ( n  <=   0L )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );          // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-          long  r  =  random . nextLong ();          long  m  =  n  -   1 ;          // power of two          if   (( n  &  m )   ==   0L )   {              return  r  &  m ;          }          // reject over-represented candidates          long  u  =  r  >>>
 
1
;

        
while
 
(

+
 m 

 
(

=
 u 
%
 n
)
 
<   0L )   {             u  =  random . nextLong ()   >>>
 
1
;

        
}

        
return
 r
;

    
}

    
///////////////////////////////////////////////////////////////////////////

    
//  STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA

    
//  THE STATIC METHODS ABOVE.

    
///////////////////////////////////////////////////////////////////////////

    
/**

     * Returns a random real number uniformly in [0, 1).

     * 

     * 
@return
     a random real number uniformly in [0, 1)

     * 
@deprecated
 Replaced by {
@link
 #uniform()}.

     */

    @
Deprecated

    
public
 
static
 
double
 random
()
 
{

        
return
 uniform
();

    
}

    
/**

     * Returns a random integer uniformly in [a, b).

     * 

     * 
@param
  a the left endpoint

     * 
@param
  b the right endpoint

     * 
@return
 a random integer uniformly in [a, b)

     * 
@throws
 IllegalArgumentException if {
@code
 b <= a}      *  @throws  IllegalArgumentException if { @code  b - a >= Integer.MAX_VALUE}

     */

    
public
 
static
 
int
 uniform
(
int
 a
,
 
int
 b
)
 
{

        
if
 
((

<=  a )   ||   (( long )  b  -  a  >=
 
Integer
.
MAX_VALUE
))
 
{

            
throw
 
new
 
IllegalArgumentException
(
“invalid range: [”
 
+
 a 
+
 
“, ”
 
+
 b 
+
 
“)”
);

        
}

        
return
 a 
+
 uniform
(


 a
);

    
}

    
/**

     * Returns a random real number uniformly in [a, b).

     * 

     * 
@param
  a the left endpoint

     * 
@param
  b the right endpoint

     * 
@return
 a random real number uniformly in [a, b)

     * 
@throws
 IllegalArgumentException unless {
@code
 a < b}      */      public   static   double  uniform ( double  a ,   double  b )   {          if   ( ! ( a  <  b ))   {              throw   new   IllegalArgumentException ( "invalid range: ["   +  a  +   ", "   +  b  +   ")" );          }          return  a  +  uniform ()   *   ( b - a );      }      /**      * Returns a random boolean from a Bernoulli distribution with success      * probability p.

     *

     * 
@param
  p the probability of returning {
@code
 true}

     * 
@return
 {
@code
 true} with probability {
@code
 p} and

     *         {
@code
 false} with probability {
@code
 1 – p}

     * 
@throws
 IllegalArgumentException unless {
@code
 0} ≤ {
@code
 p} ≤ {
@code
 1.0}

     */

    
public
 
static
 
boolean
 bernoulli
(
double
 p
)
 
{

        
if
 
(
!
(

>=
 
0.0
 
&&
 p 
<=   1.0 ))              throw   new   IllegalArgumentException ( "probability p must be between 0.0 and 1.0: "   +  p );          return  uniform ()   <  p ;      }      /**      * Returns a random boolean from a Bernoulli distribution with success      * probability 1/2.      *       *  @return  { @code  true} with probability 1/2 and      *         { @code  false} with probability 1/2      */      public   static   boolean  bernoulli ()   {          return  bernoulli ( 0.5 );      }      /**      * Returns a random real number from a standard Gaussian distribution.      *       *  @return  a random real number from a standard Gaussian distribution      *         (mean 0 and standard deviation 1).      */      public   static   double  gaussian ()   {          // use the polar form of the Box-Muller transform          double  r ,  x ,  y ;          do   {             x  =  uniform ( - 1.0 ,   1.0 );             y  =  uniform ( - 1.0 ,   1.0 );             r  =  x * x  +  y * y ;          }   while   ( r  >=
 
1
 
||
 r 
==
 
0
);

        
return
 x 
*
 
Math
.
sqrt
(

2
 
*
 
Math
.
log
(
r
)
 
/
 r
);

        
// Remark:  y * Math.sqrt(-2 * Math.log(r) / r)

        
// is an independent random gaussian

    
}

    
/**

     * Returns a random real number from a Gaussian distribution with mean μ

     * and standard deviation σ.

     * 

     * 
@param
  mu the mean

     * 
@param
  sigma the standard deviation

     * 
@return
 a real number distributed according to the Gaussian distribution

     *         with mean {
@code
 mu} and standard deviation {
@code
 sigma}

     */

    
public
 
static
 
double
 gaussian
(
double
 mu
,
 
double
 sigma
)
 
{

        
return
 mu 
+
 sigma 
*
 gaussian
();

    
}

    
/**

     * Returns a random integer from a geometric distribution with success

     * probability p.

     * The integer represents the number of independent trials

     * before the first success.

     * 

     * 
@param
  p the parameter of the geometric distribution

     * 
@return
 a random integer from a geometric distribution with success

     *         probability {
@code
 p}; or {
@code
 Integer.MAX_VALUE} if

     *         {
@code
 p} is (nearly) equal to {
@code
 1.0}.

     * 
@throws
 IllegalArgumentException unless {
@code
 p >= 0.0} and {
@code
 p <= 1.0}      */      public   static   int  geometric ( double  p )   {          if   ( ! ( p  >=
 
0
))
 
{

            
throw
 
new
 
IllegalArgumentException
(
“probability p must be greater than 0: ”
 
+
 p
);

        
}

        
if
 
(
!
(

<=   1.0 ))   {              throw   new   IllegalArgumentException ( "probability p must not be larger than 1: "   +  p );          }          // using algorithm given by Knuth          return   ( int )   Math . ceil ( Math . log ( uniform ())   /   Math . log ( 1.0   -  p ));      }      /**      * Returns a random integer from a Poisson distribution with mean λ.      *      *  @param   lambda the mean of the Poisson distribution      *  @return  a random integer from a Poisson distribution with mean { @code  lambda}      *  @throws  IllegalArgumentException unless { @code  lambda > 0.0} and not infinite

     */

    
public
 
static
 
int
 poisson
(
double
 lambda
)
 
{

        
if
 
(
!
(
lambda 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must be positive: ”
 
+
 lambda
);

        
if
 
(
Double
.
isInfinite
(
lambda
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must not be infinite: ”
 
+
 lambda
);

        
// using algorithm given by Knuth

        
// see http://en.wikipedia.org/wiki/Poisson_distribution

        
int
 k 
=
 
0
;

        
double
 p 
=
 
1.0
;

        
double
 expLambda 
=
 
Math
.
exp
(

lambda
);

        
do
 
{

            k
++
;

            p 
*=
 uniform
();

        
}
 
while
 
(

>=
 expLambda
);

        
return
 k

1
;

    
}

    
/**

     * Returns a random real number from the standard Pareto distribution.

     *

     * 
@return
 a random real number from the standard Pareto distribution

     */

    
public
 
static
 
double
 pareto
()
 
{

        
return
 pareto
(
1.0
);

    
}

    
/**

     * Returns a random real number from a Pareto distribution with

     * shape parameter α.

     *

     * 
@param
  alpha shape parameter

     * 
@return
 a random real number from a Pareto distribution with shape

     *         parameter {
@code
 alpha}

     * 
@throws
 IllegalArgumentException unless {
@code
 alpha > 0.0}

     */

    
public
 
static
 
double
 pareto
(
double
 alpha
)
 
{

        
if
 
(
!
(
alpha 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“alpha must be positive: ”
 
+
 alpha
);

        
return
 
Math
.
pow
(
1
 

 uniform
(),
 

1.0
/
alpha
)
 

 
1.0
;

    
}

    
/**

     * Returns a random real number from the Cauchy distribution.

     *

     * 
@return
 a random real number from the Cauchy distribution.

     */

    
public
 
static
 
double
 cauchy
()
 
{

        
return
 
Math
.
tan
(
Math
.
PI 
*
 
(
uniform
()
 

 
0.5
));

    
}

    
/**

     * Returns a random integer from the specified discrete distribution.

     *

     * 
@param
  probabilities the probability of occurrence of each integer

     * 
@return
 a random integer from a discrete distribution:

     *         {
@code
 i} with probability {
@code
 probabilities[i]}

     * 
@throws
 IllegalArgumentException if {
@code
 probabilities} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if sum of array entries is not (very nearly) equal to {
@code
 1.0}

     * 
@throws
 IllegalArgumentException unless {
@code
 probabilities[i] >= 0.0} for each index {
@code
 i}

     */

    
public
 
static
 
int
 discrete
(
double
[]
 probabilities
)
 
{

        
if
 
(
probabilities 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument array is null”
);

        
double
 EPSILON 
=
 
1.0E-14
;

        
double
 sum 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  probabilities . length ;  i ++ )   {              if   ( ! ( probabilities [ i ]   >=
 
0.0
))

                
throw
 
new
 
IllegalArgumentException
(
“array entry ”
 
+
 i 
+
 
” must be nonnegative: ”
 
+
 probabilities
[
i
]);

            sum 
+=
 probabilities
[
i
];

        
}

        
if
 
(
sum 
>
 
1.0
 
+
 EPSILON 
||
 sum 
<   1.0   -  EPSILON )              throw   new   IllegalArgumentException ( "sum of array entries does not approximately equal 1.0: "   +  sum );          // the for loop may not return a value when both r is (nearly) 1.0 and when the          // cumulative sum is less than 1.0 (as a result of floating-point roundoff error)          while   ( true )   {              double  r  =  uniform ();             sum  =   0.0 ;              for   ( int  i  =   0 ;  i  <  probabilities . length ;  i ++ )   {                 sum  =  sum  +  probabilities [ i ];                  if   ( sum  >
 r
)
 
return
 i
;

            
}

        
}

    
}

    
/**

     * Returns a random integer from the specified discrete distribution.

     *

     * 
@param
  frequencies the frequency of occurrence of each integer

     * 
@return
 a random integer from a discrete distribution:

     *         {
@code
 i} with probability proportional to {
@code
 frequencies[i]}

     * 
@throws
 IllegalArgumentException if {
@code
 frequencies} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if all array entries are {
@code
 0}

     * 
@throws
 IllegalArgumentException if {
@code
 frequencies[i]} is negative for any index {
@code
 i}

     * 
@throws
 IllegalArgumentException if sum of frequencies exceeds {
@code
 Integer.MAX_VALUE} (231 – 1)

     */

    
public
 
static
 
int
 discrete
(
int
[]
 frequencies
)
 
{

        
if
 
(
frequencies 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument array is null”
);

        
long
 sum 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  frequencies . length ;  i ++ )   {              if   ( frequencies [ i ]   <   0 )                  throw   new   IllegalArgumentException ( "array entry "   +  i  +   " must be nonnegative: "   +  frequencies [ i ]);             sum  +=  frequencies [ i ];          }          if   ( sum  ==   0 )              throw   new   IllegalArgumentException ( "at least one array entry must be positive" );          if   ( sum  >=
 
Integer
.
MAX_VALUE
)

            
throw
 
new
 
IllegalArgumentException
(
“sum of frequencies overflows an int”
);

        
// pick index i with probabilitity proportional to frequency

        
double
 r 
=
 uniform
((
int
)
 sum
);

        sum 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  frequencies . length ;  i ++ )   {             sum  +=  frequencies [ i ];              if   ( sum  >
 r
)
 
return
 i
;

        
}

        
// can’t reach here

        
assert
 
false
;

        
return
 

1
;

    
}

    
/**

     * Returns a random real number from an exponential distribution

     * with rate λ.

     * 

     * 
@param
  lambda the rate of the exponential distribution

     * 
@return
 a random real number from an exponential distribution with

     *         rate {
@code
 lambda}

     * 
@throws
 IllegalArgumentException unless {
@code
 lambda > 0.0}

     */

    
public
 
static
 
double
 exp
(
double
 lambda
)
 
{

        
if
 
(
!
(
lambda 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must be positive: ”
 
+
 lambda
);

        
return
 

Math
.
log
(
1
 

 uniform
())
 
/
 lambda
;

    
}

    
/**

     * Rearranges the elements of the specified array in uniformly random order.

     *

     * 
@param
  a the array to shuffle

     * 
@throws
 IllegalArgumentException if {
@code
 a} is {
@code
 null}

     */

    
public
 
static
 
void
 shuffle
(
Object
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              Object  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( double []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              double  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( int []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              int  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( char []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              char  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      *       */      public   static   void  shuffle ( Object []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              Object  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   void  shuffle ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              double  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   void  shuffle ( int []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              int  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Returns a uniformly random permutation of n elements.

     *

     * 
@param
  n number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n} is negative

     * 
@return
 an array of length {
@code
 n} that is a uniformly random permutation

     *         of {
@code
 0}, {
@code
 1}, …, {
@code
 n-1}

     */

    
public
 
static
 
int
[]
 permutation
(
int
 n
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "argument is negative" );          int []  perm  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             perm [ i ]   =  i ;         shuffle ( perm );          return  perm ;      }      /**      * Returns a uniformly random permutation of k of n elements.

     *

     * 
@param
  n number of elements

     * 
@param
  k number of elements to select

     * 
@throws
 IllegalArgumentException if {
@code
 n} is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= k <= n}      *  @return  an array of length { @code  k} that is a uniformly random permutation      *         of { @code  k} of the elements from { @code  0}, { @code  1}, ..., { @code  n-1}      */      public   static   int []  permutation ( int  n ,   int  k )   {          if   ( n  <   0 )   throw   new   IllegalArgumentException ( "argument is negative" );          if   ( k  <   0   ||  k  >
 n
)
 
throw
 
new
 
IllegalArgumentException
(
“k must be between 0 and n”
);

        
int
[]
 perm 
=
 
new
 
int
[
k
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  k ;  i ++ )   {              int  r  =  uniform ( i + 1 );      // between 0 and i             perm [ i ]   =  perm [ r ];             perm [ r ]   =  i ;          }          for   ( int  i  =  k ;  i  <  n ;  i ++ )   {              int  r  =  uniform ( i + 1 );      // between 0 and i              if   ( r  <  k )  perm [ r ]   =  i ;          }          return  perm ;      }      // throw an IllegalArgumentException if x is null      // (x can be of type Object[], double[], int[], ...)      private   static   void  validateNotNull ( Object  x )   {          if   ( x  ==   null )   {              throw   new   IllegalArgumentException ( "argument is null" );          }      }      // throw an exception unless 0 <= lo <= hi <= length      private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {          if   ( lo  <   0   ||  hi  >
 length 
||
 lo 
>
 hi
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“subarray indices out of bounds: [”
 
+
 lo 
+
 
“, ”
 
+
 hi 
+
 
“)”
);

        
}

    
}

    
/**

     * Unit tests the methods in this class.

     *

     * 
@param
 args the command-line arguments

     */

    public static void main(String[] args) {

        int n = Integer.parseInt(args[0]);

        if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1]));

        double[] probabilities = { 0.5, 0.3, 0.1, 0.1 };

        int[] frequencies = { 5, 3, 1, 1 };

        String[] a = “A B C D E F G”.split(” “);

        StdOut.println(“seed = ” + StdRandom.getSeed());

        for (int i = 0; i < n; i++) {             StdOut.printf("%2d ",   uniform(100));             StdOut.printf("%8.5f ", uniform(10.0, 99.0));             StdOut.printf("%5b ",   bernoulli(0.5));             StdOut.printf("%7.5f ", gaussian(9.0, 0.2));             StdOut.printf("%1d ",   discrete(probabilities));             StdOut.printf("%1d ",   discrete(frequencies));             StdOut.printf("%11d ",  uniform(100000000000L));             StdRandom.shuffle(a);             for (String s : a)                 StdOut.print(s);             StdOut.println();         }     } } /****************************************************************************** *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne. * *  This file is part of algs4.jar, which accompanies the textbook * *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne, *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X. *      http://algs4.cs.princeton.edu * * *  algs4.jar is free software: you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation, either version 3 of the License, or *  (at your option) any later version. * *  algs4.jar is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with algs4.jar.  If not, see http://www.gnu.org/licenses. ******************************************************************************/ edu/princeton/cs/algs4/StdStats.java edu/princeton/cs/algs4/StdStats.java /******************************************************************************  *  Compilation:  javac StdStats.java  *  Execution:    java StdStats < input.txt  *  Dependencies: StdOut.java  *  *  Library of statistical functions.  *  *  The test client reads an array of real numbers from standard  *  input, and computes the minimum, mean, maximum, and  *  standard deviation.  *  *  The functions all throw a java.lang.IllegalArgumentException  *  if the array passed in as an argument is null.  *  *  The floating-point functions all return NaN if any input is NaN.  *  *  Unlike Math.min() and Math.max(), the min() and max() functions  *  do not differentiate between -0.0 and 0.0.  *  *  % more tiny.txt  *  5  *  3.0 1.0 2.0 5.0 4.0  *  *  % java StdStats < tiny.txt  *         min   1.000  *        mean   3.000  *         max   5.000  *     std dev   1.581  *  *  Should these funtions use varargs instead of array arguments?  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  StdStats} class provides static methods for computing  *  statistics such as min, max, mean, sample standard deviation, and  *  sample variance.  *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdStats
 
{

    
private
 
StdStats
()
 
{
 
}

    
/**

     * Returns the maximum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the maximum value in the array {
@code
 a[]};

     *         {
@code
 Double.NEGATIVE_INFINITY} if no such value

     */

    
public
 
static
 
double
 max
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
double
 max 
=
 
Double
.
NEGATIVE_INFINITY
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the maximum value in the specified subarray.

     *

     * 
@param
  a the array

     * 
@param
  lo the left endpoint of the subarray (inclusive)

     * 
@param
  hi the right endpoint of the subarray (exclusive)

     * 
@return
 the maximum value in the subarray {
@code
 a[lo..hi)};

     *         {
@code
 Double.NEGATIVE_INFINITY} if no such value

     * 
@throws
 IllegalArgumentException if {
@code
 a} is {
@code
 null}

     * 
@throws
 IllegalArgumentException unless {
@code
 (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  max ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  max  =   Double . NEGATIVE_INFINITY ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the maximum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the maximum value in the array {
@code
 a[]};

     *         {
@code
 Integer.MIN_VALUE} if no such value

     */

    
public
 
static
 
int
 max
(
int
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 max 
=
 
Integer
.
MIN_VALUE
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the minimum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the minimum value in the array {
@code
 a[]};

     *         {
@code
 Double.POSITIVE_INFINITY} if no such value

     */

    
public
 
static
 
double
 min
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
double
 min 
=
 
Double
.
POSITIVE_INFINITY
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the minimum value in the specified subarray.      *      *  @param   a the array      *  @param   lo the left endpoint of the subarray (inclusive)      *  @param   hi the right endpoint of the subarray (exclusive)      *  @return  the maximum value in the subarray { @code  a[lo..hi)};      *         { @code  Double.POSITIVE_INFINITY} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  min ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  min  =   Double . POSITIVE_INFINITY ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the minimum value in the specified array.      *      *  @param   a the array      *  @return  the minimum value in the array { @code  a[]};      *         { @code  Integer.MAX_VALUE} if no such value      */      public   static   int  min ( int []  a )   {         validateNotNull ( a );          int  min  =   Integer . MAX_VALUE ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the average value in the specified array.      *      *  @param   a the array      *  @return  the average value in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  mean ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  sum  =  sum ( a );          return  sum  /  a . length ;      }      /**      * Returns the average value in the specified subarray.      *      *  @param  a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the average value in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  mean ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  sum  =  sum ( a ,  lo ,  hi );          return  sum  /  length ;      }      /**      * Returns the average value in the specified array.      *      *  @param   a the array      *  @return  the average value in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  mean ( int []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          int  sum  =  sum ( a );          return   1.0   *  sum  /  a . length ;      }      /**      * Returns the sample variance in the specified array.      *      *  @param   a the array      *  @return  the sample variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  var ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( a . length  -   1 );      }      /**      * Returns the sample variance in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sample variance in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  var ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a ,  lo ,  hi );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( length  -   1 );      }      /**      * Returns the sample variance in the specified array.      *      *  @param   a the array      *  @return  the sample variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  var ( int []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( a . length  -   1 );      }      /**      * Returns the population variance in the specified array.      *      *  @param   a the array      *  @return  the population variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  varp ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /  a . length ;      }      /**      * Returns the population variance in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the population variance in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  varp ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a ,  lo ,  hi );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /  length ;      }      /**      * Returns the sample standard deviation in the specified array.      *      *  @param   a the array      *  @return  the sample standard deviation in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  stddev ( double []  a )   {         validateNotNull ( a );          return   Math . sqrt ( var ( a ));      }      /**      * Returns the sample standard deviation in the specified array.      *      *  @param   a the array      *  @return  the sample standard deviation in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  stddev ( int []  a )   {         validateNotNull ( a );          return   Math . sqrt ( var ( a ));      }      /**      * Returns the sample standard deviation in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sample standard deviation in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  stddev ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          return   Math . sqrt ( var ( a ,  lo ,  hi ));      }      /**      * Returns the population standard deviation in the specified array.      *      *  @param   a the array      *  @return  the population standard deviation in the array;      *         { @code  Double.NaN} if no such value      */      public   static   double  stddevp ( double []  a )   {         validateNotNull ( a );          return   Math . sqrt ( varp ( a ));      }      /**      * Returns the population standard deviation in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the population standard deviation in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  stddevp ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          return   Math . sqrt ( varp ( a ,  lo ,  hi ));      }      /**      * Returns the sum of all values in the specified array.      *      *  @param   a the array      *  @return  the sum of all values in the array { @code  a[]};      *         { @code  0.0} if no such value      */      private   static   double  sum ( double []  a )   {         validateNotNull ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }      /**      * Returns the sum of all values in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sum of all values in the subarray { @code  a[lo..hi)};      *         { @code  0.0} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      private   static   double  sum ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }      /**      * Returns the sum of all values in the specified array.      *      *  @param   a the array      *  @return  the sum of all values in the array { @code  a[]};      *         { @code  0.0} if no such value      */      private   static   int  sum ( int []  a )   {         validateNotNull ( a );          int  sum  =   0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }     /**      * Plots the points (0, a0), (1, a1), …,

     * (n-1, an-1) to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotPoints
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
StdDraw
.
setPenRadius
(
1.0
 
/
 
(
3.0
 
*
 n
));

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              StdDraw . point ( i ,  a [ i ]);          }      }     /**      * Plots the line segments connecting       * (iai) to

     * (i+1, ai+1) for 

     * each i to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotLines
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
StdDraw
.
setPenRadius
();

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              StdDraw . line ( i - 1 ,  a [ i - 1 ],  i ,  a [ i ]);          }      }     /**      * Plots bars from (0, ai) to

     * (ai) for each i

     * to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotBars
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              StdDraw . filledRectangle ( i ,  a [ i ] / 2 ,   0.25 ,  a [ i ] / 2 );          }      }      // throw an IllegalArgumentException if x is null      // (x is either of type double[] or int[])      private   static   void  validateNotNull ( Object  x )   {          if   ( x  ==   null )              throw   new   IllegalArgumentException ( "argument is null" );      }      // throw an exception unless 0 <= lo <= hi <= length      private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {          if   ( lo  <   0   ||  hi  >
 length 
||
 lo 
>
 hi
)

            
throw
 
new
 
IllegalArgumentException
(
“subarray indices out of bounds: [”
 
+
 lo 
+
 
“, ”
 
+
 hi 
+
 
“)”
);

    
}

   
/**

     * Unit tests {
@code
 StdStats}.

     * Convert command-line arguments to array of doubles and call various methods.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
double
[]
 a 
=
 
StdArrayIO
.
readDouble1D
();

        
StdOut
.
printf
(
”       min %10.3f\n”
,
 min
(
a
));

        
StdOut
.
printf
(
”      mean %10.3f\n”
,
 mean
(
a
));

        
StdOut
.
printf
(
”       max %10.3f\n”
,
 max
(
a
));

        
StdOut
.
printf
(
”    stddev %10.3f\n”
,
 stddev
(
a
));

        
StdOut
.
printf
(
”       var %10.3f\n”
,
 var
(
a
));

        
StdOut
.
printf
(
”   stddevp %10.3f\n”
,
 stddevp
(
a
));

        
StdOut
.
printf
(
”      varp %10.3f\n”
,
 varp
(
a
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/ST.java
edu/princeton/cs/algs4/ST.java
/******************************************************************************

 *  Compilation:  javac ST.java

 *  Execution:    java ST < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyST.txt  *    *  Sorted symbol table implementation using a java.util.TreeMap.  *  Does not allow duplicates.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; import  java . util . NoSuchElementException ; import  java . util . TreeMap ; /**  *  The { @code  ST} class represents an ordered symbol table of generic  *  key-value pairs.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides ordered methods for finding the minimum,

 *  maximumfloor, and ceiling.

 *  It also provides a keys method for iterating over all of the keys.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  It requires that

 *  the key type implements the {
@code
 Comparable} interface and calls the

 *  {
@code
 compareTo()} and method to compare two keys. It does not call either

 *  {
@code
 equals()} or {
@code
 hashCode()}.

 *  

 *  This implementation uses a red-black BST.

 *  The putgetcontainsremove,

 *  minimummaximumceiling, and floor

 *  operations each take Θ(log n) time in the worst case,

 *  where n is the number of key-value pairs in the symbol table.

 *  The size and is-empty operations take Θ(1) time.

 *  Construction takes Θ(1) time.

 *  

 *  For additional documentation, see

 *  Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *

 *  
@param
  the generic type of keys in this symbol table

 *  
@param
  the generic type of values in this symbol table

 */

public
 
class
 ST
< Key   extends   Comparable < Key >
,
 
Value
>
 
implements
 
Iterable
< Key >
 
{

    
private
 
TreeMap
< Key ,   Value >
 st
;

    
/**

     * Initializes an empty symbol table.

     */

    
public
 ST
()
 
{

        st 
=
 
new
 
TreeMap
< Key ,   Value >
();

    
}

    
/**

     * Returns the value associated with the given key in this symbol table.

     *

     * 
@param
  key the key

     * 
@return
 the value associated with the given key if the key is in this symbol table;

     *         {
@code
 null} if the key is not in this symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls get() with null key”
);

        
return
 st
.
get
(
key
);

    
}

    
/**

     * Inserts the specified key-value pair into the symbol table, overwriting the old 

     * value with the new value if the symbol table already contains the specified key.

     * Deletes the specified key (and its associated value) from this symbol table

     * if the specified value is {
@code
 null}.

     *

     * 
@param
  key the key

     * 
@param
  val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
Key
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls put() with null key”
);

        
if
 
(
val 
==
 
null
)
 st
.
remove
(
key
);

        
else
             st
.
put
(
key
,
 val
);

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).

     * This is equivalent to {
@code
 remove()}, but we plan to deprecate {
@code
 delete()}.

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 delete
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls delete() with null key”
);

        st
.
remove
(
key
);

    
}

    
/**

     * Removes the specified key and its associated value from this symbol table     

     * (if the key is in this symbol table).

     * This is equivalent to {
@code
 delete()}, but we plan to deprecate {
@code
 delete()}.

     *

     * 
@param
  key the key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 remove
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls remove() with null key”
);

        st
.
remove
(
key
);

    
}

    
/**

     * Returns true if this symbol table contain the given key.

     *

     * 
@param
  key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key} and

     *         {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“calls contains() with null key”
);

        
return
 st
.
containsKey
(
key
);

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     *

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 st
.
size
();

    
}

    
/**

     * Returns true if this symbol table is empty.

     *

     * 
@return
 {
@code
 true} if this symbol table is empty and {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns all keys in this symbol table.

     * 

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     *

     * 
@return
 all keys in this symbol table

     */

    
public
 
Iterable
< Key >
 keys
()
 
{

        
return
 st
.
keySet
();

    
}

    
/**

     * Returns all of the keys in this symbol table.

     * To iterate over all of the keys in a symbol table named {
@code
 st}, use the

     * foreach notation: {
@code
 for (Key key : st)}.

     * 

     * This method is provided for backward compatibility with the version from

     * Introduction to Programming in Java: An Interdisciplinary Approach.

     *

     * 
@return
     an iterator to all of the keys in this symbol table

     * 
@deprecated
 Replaced by {
@link
 #keys()}.

     */

    @
Deprecated

    
public
 
Iterator
< Key >
 iterator
()
 
{

        
return
 st
.
keySet
().
iterator
();

    
}

    
/**

     * Returns the smallest key in this symbol table.

     *

     * 
@return
 the smallest key in this symbol table

     * 
@throws
 NoSuchElementException if this symbol table is empty

     */

    
public
 
Key
 min
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls min() with empty symbol table”
);

        
return
 st
.
firstKey
();

    
}

    
/**

     * Returns the largest key in this symbol table.

     *

     * 
@return
 the largest key in this symbol table

     * 
@throws
 NoSuchElementException if this symbol table is empty

     */

    
public
 
Key
 max
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“calls max() with empty symbol table”
);

        
return
 st
.
lastKey
();

    
}

    
/**

     * Returns the smallest key in this symbol table greater than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the smallest key in this symbol table greater than or equal to {
@code
 key}

     * 
@throws
 NoSuchElementException if there is no such key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 ceiling
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to ceiling() is null”
);

        
Key
 k 
=
 st
.
ceilingKey
(
key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“argument to ceiling() is too large”
);

        
return
 k
;

    
}

    
/**

     * Returns the largest key in this symbol table less than or equal to {
@code
 key}.

     *

     * 
@param
  key the key

     * 
@return
 the largest key in this symbol table less than or equal to {
@code
 key}

     * 
@throws
 NoSuchElementException if there is no such key

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Key
 floor
(
Key
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to floor() is null”
);

        
Key
 k 
=
 st
.
floorKey
(
key
);

        
if
 
(

==
 
null
)
 
throw
 
new
 
NoSuchElementException
(
“argument to floor() is too small”
);

        
return
 k
;

    
}

    
/**

     * Unit tests the {
@code
 ST} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        ST
< String ,   Integer >
 st 
=
 
new
 ST
< String ,   Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
for
 
(
String
 s 
:
 st
.
keys
())

            
StdOut
.
println
(

+
 
” ”
 
+
 st
.
get
(
s
));

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/StopwatchCPU.java
edu/princeton/cs/algs4/StopwatchCPU.java
/******************************************************************************

 *  Compilation:  javac StopwatchCPU.java

 *  Execution:    java StopwtachCPU n

 *  Dependencies: none

 *

 *  A version of Stopwatch.java that measures CPU time on a single

 *  core or processor (instead of wall clock time).

 *

 *  % java8 StopwatchCPU 100000000

 *  6.666667e+11 (1.05 seconds)

 *  6.666667e+11 (7.50 seconds)

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

import
 java
.
lang
.
management
.
ThreadMXBean
;

import
 java
.
lang
.
management
.
ManagementFactory
;

/**

 *  The {
@code
 StopwatchCPU} data type is for measuring

 *  the CPU time used during a programming task.

 *

 *  See {
@link
 Stopwatch} for a version that measures wall-clock time

 *  (the real time that elapses).

 *

 *  
@author
 Josh Hug

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
StopwatchCPU
 
{

    
private
 
static
 
final
 
double
 NANOSECONDS_PER_SECOND 
=
 
1000000000
;

    
private
 
final
 
ThreadMXBean
 threadTimer
;

    
private
 
final
 
long
 start
;

            

    
/**

     * Initializes a new stopwatch.

     */

    
public
 
StopwatchCPU
()
 
{
  

        threadTimer 
=
 
ManagementFactory
.
getThreadMXBean
();

        start 
=
 threadTimer
.
getCurrentThreadCpuTime
();

    
}
   

        

    
/**

     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.

     *

     * 
@return
 elapsed CPU time (in seconds) since the stopwatch was created

     */

    
public
 
double
 elapsedTime
()
 
{

        
long
 now 
=
 threadTimer
.
getCurrentThreadCpuTime
();

        
return
 
(
now 

 start
)
 
/
 NANOSECONDS_PER_SECOND
;

    
}

    
/**

     * Unit tests the {
@code
 StopwatchCPU} data type.

     * Takes a command-line argument {
@code
 n} and computes the 

     * sum of the square roots of the first {
@code
 n} positive integers,

     * first using {
@code
 Math.sqrt()}, then using {
@code
 Math.pow()}.

     * It prints to standard output the sum and the amount of time to

     * compute the sum. Note that the discrete sum can be approximated by

     * an integral – the sum should be approximately 2/3 * (n^(3/2) – 1).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
// sum of square roots of integers from 1 to n using Math.sqrt(x).

        
StopwatchCPU
 timer1 
=
 
new
 
StopwatchCPU
();

        
double
 sum1 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {             sum1  +=   Math . sqrt ( i );          }          double  time1  =  timer1 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum1 ,  time1 );          // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).          StopwatchCPU  timer2  =   new   StopwatchCPU ();          double  sum2  =   0.0 ;          for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {             sum2  +=   Math . pow ( i ,   0.5 );          }          double  time2  =  timer2 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum2 ,  time2 );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Stopwatch.java edu/princeton/cs/algs4/Stopwatch.java /******************************************************************************  *  Compilation:  javac Stopwatch.java  *  Execution:    java Stopwatch n  *  Dependencies: none  *  *  A utility class to measure the running time (wall clock) of a program.  *  *  % java8 Stopwatch 100000000  *  6.666667e+11  0.5820 seconds  *  6.666667e+11  8.4530 seconds  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Stopwatch} data type is for measuring  *  the time that elapses between the start and end of a  *  programming task (wall-clock time).  *  *  See { @link  StopwatchCPU} for a version that measures CPU time.  *  For additional documentation,  *  see Section 1.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Stopwatch
 
{
 

    
private
 
final
 
long
 start
;

    
/**

     * Initializes a new stopwatch.

     */

    
public
 
Stopwatch
()
 
{

        start 
=
 
System
.
currentTimeMillis
();

    
}
 

    
/**

     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.

     *

     * 
@return
 elapsed CPU time (in seconds) since the stopwatch was created

     */

    
public
 
double
 elapsedTime
()
 
{

        
long
 now 
=
 
System
.
currentTimeMillis
();

        
return
 
(
now 

 start
)
 
/
 
1000.0
;

    
}

    

    
/**

     * Unit tests the {
@code
 Stopwatch} data type.

     * Takes a command-line argument {
@code
 n} and computes the 

     * sum of the square roots of the first {
@code
 n} positive integers,

     * first using {
@code
 Math.sqrt()}, then using {
@code
 Math.pow()}.

     * It prints to standard output the sum and the amount of time to

     * compute the sum. Note that the discrete sum can be approximated by

     * an integral – the sum should be approximately 2/3 * (n^(3/2) – 1).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
// sum of square roots of integers from 1 to n using Math.sqrt(x).

        
Stopwatch
 timer1 
=
 
new
 
Stopwatch
();

        
double
 sum1 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {             sum1  +=   Math . sqrt ( i );          }          double  time1  =  timer1 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum1 ,  time1 );          // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).          Stopwatch  timer2  =   new   Stopwatch ();          double  sum2  =   0.0 ;          for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {             sum2  +=   Math . pow ( i ,   0.5 );          }          double  time2  =  timer2 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum2 ,  time2 );      } }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SuffixArray.java edu/princeton/cs/algs4/SuffixArray.java /******************************************************************************  *  Compilation:  javac SuffixArray.java  *  Execution:    java SuffixArray < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/63suffix/abra.txt  *  *  A data type that computes the suffix array of a string.  *  *   % java SuffixArray < abra.txt  *    i ind lcp rnk  select  *   ---------------------------  *    0  11   -   0  "!"  *    1  10   0   1  "A!"  *    2   7   1   2  "ABRA!"  *    3   0   4   3  "ABRACADABRA!"  *    4   3   1   4  "ACADABRA!"  *    5   5   1   5  "ADABRA!"  *    6   8   0   6  "BRA!"  *    7   1   3   7  "BRACADABRA!"  *    8   4   0   8  "CADABRA!"  *    9   6   0   9  "DABRA!"  *   10   9   0  10  "RA!"  *   11   2   2  11  "RACADABRA!"  *  *  See SuffixArrayX.java for an optimized version that uses 3-way  *  radix quicksort and does not use the nested class Suffix.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  *  The { @code  SuffixArray} class represents a suffix array of a string of  *  length n.

 *  It supports the selecting the ith smallest suffix,

 *  getting the index of the ith smallest suffix,

 *  computing the length of the longest common prefix between the

 *  ith smallest suffix and the i-1st smallest suffix,

 *  and determining the rank of a query string (which is the number

 *  of suffixes strictly less than the query string).

 *  

 *  This implementation uses a nested class {
@code
 Suffix} to represent

 *  a suffix of a string (using constant time and space) and

 *  {
@code
 Arrays.sort()} to sort the array of suffixes.

 *  The index and length operations takes constant time 

 *  in the worst case. The lcp operation takes time proportional to the

 *  length of the longest common prefix.

 *  The select operation takes time proportional

 *  to the length of the suffix and should be used primarily for debugging.

 *  

 *  For alternate implementations of the same API, see

 *  {
@link
 SuffixArrayX}, which is faster in practice (uses 3-way radix quicksort)

 *  and uses less memory (does not create {
@code
 Suffix} objects)

 *  and SuffixArrayJava6.java,

 *  which relies on the constant-time substring extraction method that existed

 *  in Java 6.

 *  

 *  For additional documentation, see Section 6.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
SuffixArray
 
{

    
private
 
Suffix
[]
 suffixes
;

    
/**

     * Initializes a suffix array for the given {
@code
 text} string.

     * 
@param
 text the input string

     */

    
public
 
SuffixArray
(
String
 text
)
 
{

        
int
 n 
=
 text
.
length
();

        
this
.
suffixes 
=
 
new
 
Suffix
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             suffixes [ i ]   =   new   Suffix ( text ,  i );          Arrays . sort ( suffixes );      }      private   static   class   Suffix   implements   Comparable < Suffix >
 
{

        
private
 
final
 
String
 text
;

        
private
 
final
 
int
 index
;

        
private
 
Suffix
(
String
 text
,
 
int
 index
)
 
{

            
this
.
text 
=
 text
;

            
this
.
index 
=
 index
;

        
}

        
private
 
int
 length
()
 
{

            
return
 text
.
length
()
 

 index
;

        
}

        
private
 
char
 charAt
(
int
 i
)
 
{

            
return
 text
.
charAt
(
index 
+
 i
);

        
}

        
public
 
int
 compareTo
(
Suffix
 that
)
 
{

            
if
 
(
this
 
==
 that
)
 
return
 
0
;
  
// optimization

            
int
 n 
=
 
Math
.
min
(
this
.
length
(),
 that
.
length
());

            
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {                  if   ( this . charAt ( i )   <  that . charAt ( i ))   return   - 1 ;                  if   ( this . charAt ( i )   >
 that
.
charAt
(
i
))
 
return
 
+
1
;

            
}

            
return
 
this
.
length
()
 

 that
.
length
();

        
}

        
public
 
String
 toString
()
 
{

            
return
 text
.
substring
(
index
);

        
}

    
}

    
/**

     * Returns the length of the input string.

     * 
@return
 the length of the input string

     */

    
public
 
int
 length
()
 
{

        
return
 suffixes
.
length
;

    
}

    
/**

     * Returns the index into the original string of the ith smallest suffix.

     * That is, {
@code
 text.substring(sa.index(i))} is the ith smallest suffix.

     * 
@param
 i an integer between 0 and n-1

     * 
@return
 the index into the original string of the ith smallest suffix

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 0 <= i < n}      */      public   int  index ( int  i )   {          if   ( i  <   0   ||  i  >=
 suffixes
.
length
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 suffixes
[
i
].
index
;

    
}

    
/**

     * Returns the length of the longest common prefix of the ith

     * smallest suffix and the i-1st smallest suffix.

     * 
@param
 i an integer between 1 and n-1

     * 
@return
 the length of the longest common prefix of the ith

     * smallest suffix and the i-1st smallest suffix.

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 1 <= i < n}      */      public   int  lcp ( int  i )   {          if   ( i  <   1   ||  i  >=
 suffixes
.
length
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 lcpSuffix
(
suffixes
[
i
],
 suffixes
[
i

1
]);

    
}

    
// longest common prefix of s and t

    
private
 
static
 
int
 lcpSuffix
(
Suffix
 s
,
 
Suffix
 t
)
 
{

        
int
 n 
=
 
Math
.
min
(
s
.
length
(),
 t
.
length
());

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   ( s . charAt ( i )   !=  t . charAt ( i ))   return  i ;          }          return  n ;      }      /**      * Returns the ith smallest suffix as a string.

     * 
@param
 i the index

     * 
@return
 the i smallest suffix as a string

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 0 <= i < n}      */      public   String  select ( int  i )   {          if   ( i  <   0   ||  i  >=
 suffixes
.
length
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 suffixes
[
i
].
toString
();

    
}

    
/**

     * Returns the number of suffixes strictly less than the {
@code
 query} string.

     * We note that {
@code
 rank(select(i))} equals {
@code
 i} for each {
@code
 i}

     * between 0 and n-1.

     * 
@param
 query the query string

     * 
@return
 the number of suffixes strictly less than {
@code
 query}

     */

    
public
 
int
 rank
(
String
 query
)
 
{

        
int
 lo 
=
 
0
,
 hi 
=
 suffixes
.
length 

 
1
;

        
while
 
(
lo 
<=  hi )   {              int  mid  =  lo  +   ( hi  -  lo )   /   2 ;              int  cmp  =  compare ( query ,  suffixes [ mid ]);              if   ( cmp  <   0 )  hi  =  mid  -   1 ;              else   if   ( cmp  >
 
0
)
 lo 
=
 mid 
+
 
1
;

            
else
 
return
 mid
;

        
}

        
return
 lo
;

    
}

    
// compare query string to suffix

    
private
 
static
 
int
 compare
(
String
 query
,
 
Suffix
 suffix
)
 
{

        
int
 n 
=
 
Math
.
min
(
query
.
length
(),
 suffix
.
length
());

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              if   ( query . charAt ( i )   <  suffix . charAt ( i ))   return   - 1 ;              if   ( query . charAt ( i )   >
 suffix
.
charAt
(
i
))
 
return
 
+
1
;

        
}

        
return
 query
.
length
()
 

 suffix
.
length
();

    
}

    
/**

     * Unit tests the {
@code
 SuffixArray} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 s 
=
 
StdIn
.
readAll
().
replaceAll
(
“\\s+”
,
 
” ”
).
trim
();

        
SuffixArray
 suffix 
=
 
new
 
SuffixArray
(
s
);

        
// StdOut.println(“rank(” + args[0] + “) = ” + suffix.rank(args[0]));

        
StdOut
.
println
(
”  i ind lcp rnk select”
);

        
StdOut
.
println
(
“—————————”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )   {              int  index  =  suffix . index ( i );              String  ith  =   "\""   +  s . substring ( index ,   Math . min ( index  +   50 ,  s . length ()))   +   "\"" ;              assert  s . substring ( index ). equals ( suffix . select ( i ));              int  rank  =  suffix . rank ( s . substring ( index ));              if   ( i  ==   0 )   {                  StdOut . printf ( "%3d %3d %3s %3d %s\n" ,  i ,  index ,   "-" ,  rank ,  ith );              }              else   {                  int  lcp  =  suffix . lcp ( i );                  StdOut . printf ( "%3d %3d %3d %3d %s\n" ,  i ,  index ,  lcp ,  rank ,  ith );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SuffixArrayX.java edu/princeton/cs/algs4/SuffixArrayX.java /******************************************************************************  *  Compilation:  javac SuffixArrayX.java  *  Execution:    java SuffixArrayX < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/63suffix/abra.txt  *    *  A data type that computes the suffix array of a string using 3-way  *  radix quicksort.  *  *  % java SuffixArrayX < abra.txt   *    i ind lcp rnk  select  *  ---------------------------  *    0  11   -   0  !  *    1  10   0   1  A!  *    2   7   1   2  ABRA!  *    3   0   4   3  ABRACADABRA!  *    4   3   1   4  ACADABRA!  *    5   5   1   5  ADABRA!  *    6   8   0   6  BRA!  *    7   1   3   7  BRACADABRA!  *    8   4   0   8  CADABRA!  *    9   6   0   9  DABRA!  *   10   9   0  10  RA!  *   11   2   2  11  RACADABRA!  *  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  SuffixArrayX} class represents a suffix array of a string of  *  length n.

 *  It supports the selecting the ith smallest suffix,

 *  getting the index of the ith smallest suffix,

 *  computing the length of the longest common prefix between the

 *  ith smallest suffix and the i-1st smallest suffix,

 *  and determining the rank of a query string (which is the number

 *  of suffixes strictly less than the query string).

 *  

 *  This implementation uses 3-way radix quicksort to sort the array of suffixes.

 *  For a simpler (but less efficient) implementations of the same API, see

 *  {
@link
 SuffixArray}.

 *  The index and length operations takes constant time

 *  in the worst case. The lcp operation takes time proportional to the

 *  length of the longest common prefix.

 *  The select operation takes time proportional

 *  to the length of the suffix and should be used primarily for debugging.

 *  

 *  This implementation uses ‘\0’ as a sentinel and assumes that the charater

 *  ‘\0’ does not appear in the text.

 *  

 *  In practice, this algorithm runs very fast. However, in the worst-case

 *  it can be very poor (e.g., a string consisting of N copies of the same

 *  character. We do not shuffle the array of suffixes before sorting because

 *  shuffling is relatively expensive and a pathologial input for which 

 *  the suffixes start out in a bad order (e.g., sorted) is likely to be

 *  a bad input for this algorithm with or without the shuffle.

 *  

 *  For additional documentation, see Section 6.3 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
SuffixArrayX
 
{

    
private
 
static
 
final
 
int
 CUTOFF 
=
  
5
;
   
// cutoff to insertion sort (any value between 0 and 12)

    
private
 
final
 
char
[]
 text
;

    
private
 
final
 
int
[]
 index
;
   
// index[i] = j means text.substring(j) is ith largest suffix

    
private
 
final
 
int
 n
;
         
// number of characters in text

    
/**

     * Initializes a suffix array for the given {
@code
 text} string.

     * 
@param
 text the input string

     */

    
public
 
SuffixArrayX
(
String
 text
)
 
{

        n 
=
 text
.
length
();

        text 
=
 text 
+
 
‘\0’
;

        
this
.
text 
=
 text
.
toCharArray
();

        
this
.
index 
=
 
new
 
int
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )             index [ i ]   =  i ;         sort ( 0 ,  n - 1 ,   0 );      }      // 3-way string quicksort lo..hi starting at dth character      private   void  sort ( int  lo ,   int  hi ,   int  d )   {            // cutoff to insertion sort for small subarrays          if   ( hi  <=  lo  +  CUTOFF )   {             insertion ( lo ,  hi ,  d );              return ;          }          int  lt  =  lo ,  gt  =  hi ;          char  v  =  text [ index [ lo ]   +  d ];          int  i  =  lo  +   1 ;          while   ( i  <=  gt )   {              char  t  =  text [ index [ i ]   +  d ];              if        ( t  <  v )  exch ( lt ++ ,  i ++ );              else   if   ( t  >
 v
)
 exch
(
i
,
 gt

);

            
else
            i
++
;

        
}

        
// a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].          sort ( lo ,  lt - 1 ,  d );          if   ( v  >
 
0
)
 sort
(
lt
,
 gt
,
 d
+
1
);

        sort
(
gt
+
1
,
 hi
,
 d
);

    
}

    
// sort from a[lo] to a[hi], starting at the dth character

    
private
 
void
 insertion
(
int
 lo
,
 
int
 hi
,
 
int
 d
)
 
{

        
for
 
(
int
 i 
=
 lo
;
 i 
<=  hi ;  i ++ )              for   ( int  j  =  i ;  j  >
 lo 
&&
 less
(
index
[
j
],
 index
[
j

1
],
 d
);
 j

)

                exch
(
j
,
 j

1
);

    
}

    
// is text[i+d..n) < text[j+d..n) ?      private   boolean  less ( int  i ,   int  j ,   int  d )   {          if   ( i  ==  j )   return   false ;         i  =  i  +  d ;         j  =  j  +  d ;          while   ( i  <  n  &&  j  <  n )   {              if   ( text [ i ]   <  text [ j ])   return   true ;              if   ( text [ i ]   >
 text
[
j
])
 
return
 
false
;

            i
++
;

            j
++
;

        
}

        
return
 i 
>
 j
;

    
}

    
// exchange index[i] and index[j]

    
private
 
void
 exch
(
int
 i
,
 
int
 j
)
 
{

        
int
 swap 
=
 index
[
i
];

        index
[
i
]
 
=
 index
[
j
];

        index
[
j
]
 
=
 swap
;

    
}

    
/**

     * Returns the length of the input string.

     * 
@return
 the length of the input string

     */

    
public
 
int
 length
()
 
{

        
return
 n
;

    
}

    
/**

     * Returns the index into the original string of the ith smallest suffix.

     * That is, {
@code
 text.substring(sa.index(i))} is the i smallest suffix.

     * 
@param
 i an integer between 0 and n-1

     * 
@return
 the index into the original string of the ith smallest suffix

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 0 <=i < n}      */      public   int  index ( int  i )   {          if   ( i  <   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 index
[
i
];

    
}

    
/**

     * Returns the length of the longest common prefix of the ith

     * smallest suffix and the i-1st smallest suffix.

     * 
@param
 i an integer between 1 and n-1

     * 
@return
 the length of the longest common prefix of the ith

     * smallest suffix and the i-1st smallest suffix.

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 1 <= i < n}      */      public   int  lcp ( int  i )   {          if   ( i  <   1   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 lcp
(
index
[
i
],
 index
[
i

1
]);

    
}

    
// longest common prefix of text[i..n) and text[j..n)

    
private
 
int
 lcp
(
int
 i
,
 
int
 j
)
 
{

        
int
 length 
=
 
0
;

        
while
 
(

<  n  &&  j  <  n )   {              if   ( text [ i ]   !=  text [ j ])   return  length ;             i ++ ;             j ++ ;             length ++ ;          }          return  length ;      }      /**      * Returns the ith smallest suffix as a string.

     * 
@param
 i the index

     * 
@return
 the i smallest suffix as a string

     * 
@throws
 java.lang.IllegalArgumentException unless {
@code
 0 <= i < n}      */      public   String  select ( int  i )   {          if   ( i  <   0   ||  i  >=
 n
)
 
throw
 
new
 
IllegalArgumentException
();

        
return
 
new
 
String
(
text
,
 index
[
i
],
 n 

 index
[
i
]);

    
}

    
/**

     * Returns the number of suffixes strictly less than the {
@code
 query} string.

     * We note that {
@code
 rank(select(i))} equals {
@code
 i} for each {
@code
 i}

     * between 0 and n-1. 

     * 
@param
 query the query string

     * 
@return
 the number of suffixes strictly less than {
@code
 query}

     */

    
public
 
int
 rank
(
String
 query
)
 
{

        
int
 lo 
=
 
0
,
 hi 
=
 n 

 
1
;

        
while
 
(
lo 
<=  hi )   {              int  mid  =  lo  +   ( hi  -  lo )   /   2 ;              int  cmp  =  compare ( query ,  index [ mid ]);              if        ( cmp  <   0 )  hi  =  mid  -   1 ;              else   if   ( cmp  >
 
0
)
 lo 
=
 mid 
+
 
1
;

            
else
 
return
 mid
;

        
}

        
return
 lo
;

    
}
 

    
// is query < text[i..n) ?      private   int  compare ( String  query ,   int  i )   {          int  m  =  query . length ();          int  j  =   0 ;          while   ( i  <  n  &&  j  <  m )   {              if   ( query . charAt ( j )   !=  text [ i ])   return  query . charAt ( j )   -  text [ i ];             i ++ ;             j ++ ;          }          if   ( i  <  n )   return   - 1 ;          if   ( j  <  m )   return   + 1 ;          return   0 ;      }      /**      * Unit tests the { @code  SuffixArrayx} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          String  s  =   StdIn . readAll (). replaceAll ( "\n" ,   " " ). trim ();          SuffixArrayX  suffix1  =   new   SuffixArrayX ( s );          SuffixArray  suffix2  =   new   SuffixArray ( s );          boolean  check  =   true ;          for   ( int  i  =   0 ;  check  &&  i  <  s . length ();  i ++ )   {              if   ( suffix1 . index ( i )   !=  suffix2 . index ( i ))   {                  StdOut . println ( "suffix1("   +  i  +   ") = "   +  suffix1 . index ( i ));                  StdOut . println ( "suffix2("   +  i  +   ") = "   +  suffix2 . index ( i ));                  String  ith  =   "\""   +  s . substring ( suffix1 . index ( i ),   Math . min ( suffix1 . index ( i )   +   50 ,  s . length ()))   +   "\"" ;                  String  jth  =   "\""   +  s . substring ( suffix2 . index ( i ),   Math . min ( suffix2 . index ( i )   +   50 ,  s . length ()))   +   "\"" ;                  StdOut . println ( ith );                  StdOut . println ( jth );                 check  =   false ;              }          }          StdOut . println ( "  i ind lcp rnk  select" );          StdOut . println ( "---------------------------" );          for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )   {              int  index  =  suffix2 . index ( i );              String  ith  =   "\""   +  s . substring ( index ,   Math . min ( index  +   50 ,  s . length ()))   +   "\"" ;              int  rank  =  suffix2 . rank ( s . substring ( index ));              assert  s . substring ( index ). equals ( suffix2 . select ( i ));              if   ( i  ==   0 )   {                  StdOut . printf ( "%3d %3d %3s %3d  %s\n" ,  i ,  index ,   "-" ,  rank ,  ith );              }              else   {                  // int lcp  = suffix.lcp(suffix2.index(i), suffix2.index(i-1));                  int  lcp   =  suffix2 . lcp ( i );                  StdOut . printf ( "%3d %3d %3d %3d  %s\n" ,  i ,  index ,  lcp ,  rank ,  ith );              }          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/SymbolDigraph.java edu/princeton/cs/algs4/SymbolDigraph.java /******************************************************************************  *  Compilation:  javac SymbolDigraph.java  *  Execution:    java SymbolDigraph  *  Dependencies: ST.java Digraph.java In.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/routes.txt  *    *  %  java SymbolDigraph routes.txt " "  *  JFK  *     MCO  *     ATL  *     ORD  *  ATL  *     HOU  *     MCO  *  LAX  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  SymbolDigraph} class represents a digraph, where the  *  vertex names are arbitrary strings.  *  By providing mappings between string vertex names and integers,  *  it serves as a wrapper around the  *  { @link  Digraph} data type, which assumes the vertex names are integers  *  between 0 and V – 1.

 *  It also supports initializing a symbol digraph from a file.

 *  

 *  This implementation uses an {
@link
 ST} to map from strings to integers,

 *  an array to map from integers to strings, and a {
@link
 Digraph} to store

 *  the underlying graph.

 *  The indexOf and contains operations take time 

 *  proportional to log V, where V is the number of vertices.

 *  The nameOf operation takes constant time.

 *  

 *  For additional documentation, see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
SymbolDigraph
 
{

    
private
 ST
< String ,   Integer >
 st
;
  
// string -> index

    
private
 
String
[]
 keys
;
           
// index  -> string

    
private
 
Digraph
 graph
;
           
// the underlying digraph

    
/**  

     * Initializes a digraph from a file using the specified delimiter.

     * Each line in the file contains

     * the name of a vertex, followed by a list of the names

     * of the vertices adjacent to that vertex, separated by the delimiter.

     * 
@param
 filename the name of the file

     * 
@param
 delimiter the delimiter between fields

     */

    
public
 
SymbolDigraph
(
String
 filename
,
 
String
 delimiter
)
 
{

        st 
=
 
new
 ST
< String ,   Integer >
();

        
// First pass builds the index by reading strings to associate

        
// distinct strings with an index

        
In
 in 
=
 
new
 
In
(
filename
);

        
while
 
(
in
.
hasNextLine
())
 
{

            
String
[]
 a 
=
 in
.
readLine
().
split
(
delimiter
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {                  if   ( ! st . contains ( a [ i ]))                     st . put ( a [ i ],  st . size ());              }          }          // inverted index to get string keys in an array         keys  =   new   String [ st . size ()];          for   ( String  name  :  st . keys ())   {             keys [ st . get ( name )]   =  name ;          }          // second pass builds the digraph by connecting first vertex on each          // line to all others         graph  =   new   Digraph ( st . size ());         in  =   new   In ( filename );          while   ( in . hasNextLine ())   {              String []  a  =  in . readLine (). split ( delimiter );              int  v  =  st . get ( a [ 0 ]);              for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )   {                  int  w  =  st . get ( a [ i ]);                 graph . addEdge ( v ,  w );              }          }      }      /**      * Does the digraph contain the vertex named { @code  s}?      *  @param  s the name of a vertex      *  @return  { @code  true} if { @code  s} is the name of a vertex, and { @code  false} otherwise      */      public   boolean  contains ( String  s )   {          return  st . contains ( s );      }      /**      * Returns the integer associated with the vertex named { @code  s}.      *  @param  s the name of a vertex      *  @return  the integer (between 0 and V – 1) associated with the vertex named {
@code
 s}

     * 
@deprecated
 Replaced by {
@link
 #indexOf(String)}.

     */

    @
Deprecated

    
public
 
int
 index
(
String
 s
)
 
{

        
return
 st
.
get
(
s
);

    
}

    
/**

     * Returns the integer associated with the vertex named {
@code
 s}.

     * 
@param
 s the name of a vertex

     * 
@return
 the integer (between 0 and V – 1) associated with the vertex named {
@code
 s}

     */

    
public
 
int
 indexOf
(
String
 s
)
 
{

        
return
 st
.
get
(
s
);

    
}

    
/**

     * Returns the name of the vertex associated with the integer {
@code
 v}.

     * 
@param
  v the integer corresponding to a vertex (between 0 and V – 1) 

     * 
@return
 the name of the vertex associated with the integer {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      *  @deprecated  Replaced by { @link  #nameOf(int)}.      */     @ Deprecated      public   String  name ( int  v )   {         validateVertex ( v );          return  keys [ v ];      }      /**      * Returns the name of the vertex associated with the integer { @code  v}.      *  @param   v the integer corresponding to a vertex (between 0 and V – 1) 

     * 
@return
 the name of the vertex associated with the integer {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   String  nameOf ( int  v )   {         validateVertex ( v );          return  keys [ v ];      }      /**      * Returns the digraph assoicated with the symbol graph. It is the client's responsibility      * not to mutate the digraph.      *      *  @return  the digraph associated with the symbol digraph      *  @deprecated  Replaced by { @link  #digraph()}.      */     @ Deprecated      public   Digraph  G ()   {          return  graph ;      }      /**      * Returns the digraph assoicated with the symbol graph. It is the client's responsibility      * not to mutate the digraph.      *      *  @return  the digraph associated with the symbol digraph      */      public   Digraph  digraph ()   {          return  graph ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  graph . V ();          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 SymbolDigraph} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 filename  
=
 args
[
0
];

        
String
 delimiter 
=
 args
[
1
];

        
SymbolDigraph
 sg 
=
 
new
 
SymbolDigraph
(
filename
,
 delimiter
);

        
Digraph
 graph 
=
 sg
.
digraph
();

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 t 
=
 
StdIn
.
readLine
();

            
for
 
(
int
 v 
:
 graph
.
adj
(
sg
.
index
(
t
)))
 
{

                
StdOut
.
println
(
”   ”
 
+
 sg
.
name
(
v
));

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/SymbolGraph.java
edu/princeton/cs/algs4/SymbolGraph.java
/******************************************************************************

 *  Compilation:  javac SymbolGraph.java

 *  Execution:    java SymbolGraph filename.txt delimiter

 *  Dependencies: ST.java Graph.java In.java StdIn.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/41graph/routes.txt

 *                https://algs4.cs.princeton.edu/41graph/movies.txt

 *                https://algs4.cs.princeton.edu/41graph/moviestiny.txt

 *                https://algs4.cs.princeton.edu/41graph/moviesG.txt

 *                https://algs4.cs.princeton.edu/41graph/moviestopGrossing.txt

 *  

 *  %  java SymbolGraph routes.txt ” ”

 *  JFK

 *     MCO

 *     ATL

 *     ORD

 *  LAX

 *     PHX

 *     LAS

 *

 *  % java SymbolGraph movies.txt “/”

 *  Tin Men (1987)

 *     Hershey, Barbara

 *     Geppi, Cindy

 *     Jones, Kathy (II)

 *     Herr, Marcia

 *     …

 *     Blumenfeld, Alan

 *     DeBoy, David

 *  Bacon, Kevin

 *     Woodsman, The (2004)

 *     Wild Things (1998)

 *     Where the Truth Lies (2005)

 *     Tremors (1990)

 *     …

 *     Apollo 13 (1995)

 *     Animal House (1978)

 *

 * 

 *  Assumes that input file is encoded using UTF-8.

 *  % iconv -f ISO-8859-1 -t UTF-8 movies-iso8859.txt > movies.txt

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 SymbolGraph} class represents an undirected graph, where the

 *  vertex names are arbitrary strings.

 *  By providing mappings between string vertex names and integers,

 *  it serves as a wrapper around the

 *  {
@link
 Graph} data type, which assumes the vertex names are integers

 *  between 0 and V – 1.

 *  It also supports initializing a symbol graph from a file.

 *  

 *  This implementation uses an {
@link
 ST} to map from strings to integers,

 *  an array to map from integers to strings, and a {
@link
 Graph} to store

 *  the underlying graph.

 *  The indexOf and contains operations take time 

 *  proportional to log V, where V is the number of vertices.

 *  The nameOf operation takes constant time.

 *  

 *  For additional documentation, see Section 4.1 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
SymbolGraph
 
{

    
private
 ST
< String ,   Integer >
 st
;
  
// string -> index

    
private
 
String
[]
 keys
;
           
// index  -> string

    
private
 
Graph
 graph
;
             
// the underlying graph

    
/**  

     * Initializes a graph from a file using the specified delimiter.

     * Each line in the file contains

     * the name of a vertex, followed by a list of the names

     * of the vertices adjacent to that vertex, separated by the delimiter.

     * 
@param
 filename the name of the file

     * 
@param
 delimiter the delimiter between fields

     */

    
public
 
SymbolGraph
(
String
 filename
,
 
String
 delimiter
)
 
{

        st 
=
 
new
 ST
< String ,   Integer >
();

        
// First pass builds the index by reading strings to associate

        
// distinct strings with an index

        
In
 in 
=
 
new
 
In
(
filename
);

        
// while (in.hasNextLine()) {

        
while
 
(
!
in
.
isEmpty
())
 
{

            
String
[]
 a 
=
 in
.
readLine
().
split
(
delimiter
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {                  if   ( ! st . contains ( a [ i ]))                     st . put ( a [ i ],  st . size ());              }          }          // inverted index to get string keys in an array         keys  =   new   String [ st . size ()];          for   ( String  name  :  st . keys ())   {             keys [ st . get ( name )]   =  name ;          }          // second pass builds the graph by connecting first vertex on each          // line to all others         graph  =   new   Graph ( st . size ());         in  =   new   In ( filename );          while   ( in . hasNextLine ())   {              String []  a  =  in . readLine (). split ( delimiter );              int  v  =  st . get ( a [ 0 ]);              for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )   {                  int  w  =  st . get ( a [ i ]);                 graph . addEdge ( v ,  w );              }          }      }      /**      * Does the graph contain the vertex named { @code  s}?      *  @param  s the name of a vertex      *  @return  { @code  true} if { @code  s} is the name of a vertex, and { @code  false} otherwise      */      public   boolean  contains ( String  s )   {          return  st . contains ( s );      }      /**      * Returns the integer associated with the vertex named { @code  s}.      *  @param  s the name of a vertex      *  @return  the integer (between 0 and V – 1) associated with the vertex named {
@code
 s}

     * 
@deprecated
 Replaced by {
@link
 #indexOf(String)}.

     */

    @
Deprecated

    
public
 
int
 index
(
String
 s
)
 
{

        
return
 st
.
get
(
s
);

    
}

    
/**

     * Returns the integer associated with the vertex named {
@code
 s}.

     * 
@param
 s the name of a vertex

     * 
@return
 the integer (between 0 and V – 1) associated with the vertex named {
@code
 s}

     */

    
public
 
int
 indexOf
(
String
 s
)
 
{

        
return
 st
.
get
(
s
);

    
}

    
/**

     * Returns the name of the vertex associated with the integer {
@code
 v}.

     * 
@param
  v the integer corresponding to a vertex (between 0 and V – 1) 

     * 
@return
 the name of the vertex associated with the integer {
@code
 v}

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      *  @deprecated  Replaced by { @link  #nameOf(int)}.      */     @ Deprecated      public   String  name ( int  v )   {         validateVertex ( v );          return  keys [ v ];      }      /**      * Returns the name of the vertex associated with the integer { @code  v}.      *  @param   v the integer corresponding to a vertex (between 0 and V – 1) 

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      *  @return  the name of the vertex associated with the integer { @code  v}      */      public   String  nameOf ( int  v )   {         validateVertex ( v );          return  keys [ v ];      }      /**      * Returns the graph assoicated with the symbol graph. It is the client's responsibility      * not to mutate the graph.      *  @return  the graph associated with the symbol graph      *  @deprecated  Replaced by { @link  #graph()}.      */     @ Deprecated      public   Graph  G ()   {          return  graph ;      }      /**      * Returns the graph assoicated with the symbol graph. It is the client's responsibility      * not to mutate the graph.      *  @return  the graph associated with the symbol graph      */      public   Graph  graph ()   {          return  graph ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  graph . V ();          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 SymbolGraph} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 filename  
=
 args
[
0
];

        
String
 delimiter 
=
 args
[
1
];

        
SymbolGraph
 sg 
=
 
new
 
SymbolGraph
(
filename
,
 delimiter
);

        
Graph
 graph 
=
 sg
.
graph
();

        
while
 
(
StdIn
.
hasNextLine
())
 
{

            
String
 source 
=
 
StdIn
.
readLine
();

            
if
 
(
sg
.
contains
(
source
))
 
{

                
int
 s 
=
 sg
.
index
(
source
);

                
for
 
(
int
 v 
:
 graph
.
adj
(
s
))
 
{

                    
StdOut
.
println
(
”   ”
 
+
 sg
.
name
(
v
));

                
}

            
}

            
else
 
{

                
StdOut
.
println
(
“input not contain ‘”
 
+
 source 
+
 
“‘”
);

            
}

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/TarjanSCC.java
edu/princeton/cs/algs4/TarjanSCC.java
/******************************************************************************

 *  Compilation:  javac TarjanSCC.java

 *  Execution:    Java TarjanSCC V E

 *  Dependencies: Digraph.java Stack.java TransitiveClosure.java StdOut.java

 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt

 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt

 *

 *  Compute the strongly-connected components of a digraph using 

 *  Tarjan’s algorithm.

 *

 *  Runs in O(E + V) time.

 *

 *  % java TarjanSCC tinyDG.txt

 *  5 components

 *  1 

 *  0 2 3 4 5

 *  9 10 11 12

 *  6 8

 *  7 

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 TarjanSCC} class represents a data type for 

 *  determining the strong components in a digraph.

 *  The id operation determines in which strong component

 *  a given vertex lies; the areStronglyConnected operation

 *  determines whether two vertices are in the same strong component;

 *  and the count operation determines the number of strong

 *  components.

 *  

 *  The component identifier of a component is one of the

 *  vertices in the strong component: two vertices have the same component

 *  identifier if and only if they are in the same strong component.

 *  

 *  This implementation uses Tarjan’s algorithm.

 *  The constructor takes Θ(V + E) time,

 *  where V is the number of vertices and E is the

 *  number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  For alternative implementations of the same API, see

 *  {
@link
 KosarajuSharirSCC} and {
@link
 GabowSCC}.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TarjanSCC
 
{

    
private
 
boolean
[]
 marked
;
        
// marked[v] = has v been visited?

    
private
 
int
[]
 id
;
                
// id[v] = id of strong component containing v

    
private
 
int
[]
 low
;
               
// low[v] = low number of v

    
private
 
int
 pre
;
                 
// preorder number counter

    
private
 
int
 count
;
               
// number of strongly-connected components

    
private
 
Stack
< Integer >
 stack
;

    
/**

     * Computes the strong components of the digraph {
@code
 G}.

     * 
@param
 G the digraph

     */

    
public
 
TarjanSCC
(
Digraph
 G
)
 
{

        marked 
=
 
new
 
boolean
[
G
.
V
()];

        stack 
=
 
new
 
Stack
< Integer >
();

        id 
=
 
new
 
int
[
G
.
V
()];
 

        low 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {              if   ( ! marked [ v ])  dfs ( G ,  v );          }          // check that id[] gives strong components          assert  check ( G );      }      private   void  dfs ( Digraph  G ,   int  v )   {           marked [ v ]   =   true ;         low [ v ]   =  pre ++ ;          int  min  =  low [ v ];         stack . push ( v );          for   ( int  w  :  G . adj ( v ))   {              if   ( ! marked [ w ])  dfs ( G ,  w );              if   ( low [ w ]   <  min )  min  =  low [ w ];          }          if   ( min  <  low [ v ])   {             low [ v ]   =  min ;              return ;          }          int  w ;          do   {             w  =  stack . pop ();             id [ w ]   =  count ;             low [ w ]   =  G . V ();          }   while   ( w  !=  v );         count ++ ;      }      /**      * Returns the number of strong components.      *  @return  the number of strong components      */      public   int  count ()   {          return  count ;      }      /**      * Are vertices { @code  v} and { @code  w} in the same strong component?      *  @param   v one vertex      *  @param   w the other vertex      *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same      *         strong component, and { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      */      public   boolean  stronglyConnected ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  id [ v ]   ==  id [ w ];      }      /**      * Returns the component id of the strong component containing vertex { @code  v}.      *  @param   v the vertex      *  @return  the component id of the strong component containing vertex { @code  v}      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      */      public   int  id ( int  v )   {         validateVertex ( v );          return  id [ v ];      }      // does the id[] array contain the strongly connected components?      private   boolean  check ( Digraph  G )   {          TransitiveClosure  tc  =   new   TransitiveClosure ( G );          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))                      return   false ;              }          }          return   true ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  marked . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 TarjanSCC} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
TarjanSCC
 scc 
=
 
new
 
TarjanSCC
(
G
);

        
// number of connected components

        
int
 m 
=
 scc
.
count
();

        
StdOut
.
println
(

+
 
” components”
);

        
// compute list of vertices in each strong component

        
Queue
< Integer >
[]
 components 
=
 
(
Queue
< Integer >
[])
 
new
 
Queue
[
m
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {             components [ i ]   =   new   Queue < Integer >
();

        
}

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             components [ scc . id ( v )]. enqueue ( v );          }          // print results          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  v  :  components [ i ])   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/ThreeSumFast.java edu/princeton/cs/algs4/ThreeSumFast.java /******************************************************************************  *  Compilation:  javac ThreeSumFast.java  *  Execution:    java ThreeSumFast input.txt  *  Dependencies: StdOut.java In.java Stopwatch.java  *  Data files:   https://algs4.cs.princeton.edu/14analysis/1Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/2Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/4Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/8Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/16Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/32Kints.txt  *                https://algs4.cs.princeton.edu/14analysis/1Mints.txt  *  *  A program with n^2 log n running time. Reads n integers  *  and counts the number of triples that sum to exactly 0.  *  *  Limitations  *  -----------  *     - we ignore integer overflow  *     - doesn't handle case when input has duplicates  *  *  *  % java ThreeSumFast 1Kints.txt  *  70  *    *  % java ThreeSumFast 2Kints.txt  *  528  *                  *  % java ThreeSumFast 4Kints.txt  *  4039  *   *  % java ThreeSumFast 8Kints.txt  *  32074  *  *  % java ThreeSumFast 16Kints.txt  *  255181  *  *  % java ThreeSumFast 32Kints.txt  *  2052358  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; /**  *  The { @code  ThreeSumFast} class provides static methods for counting  *  and printing the number of triples in an array of distinct integers that  *  sum to 0 (ignoring integer overflow).  *  

 *  This implementation uses sorting and binary search and takes time 

 *  proportional to n^2 log n, where n is the number of integers.

 *  

 *  For additional documentation, see Section 1.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ThreeSumFast
 
{

    
// Do not instantiate.

    
private
 
ThreeSumFast
()
 
{
 
}

    
// returns true if the sorted array a[] contains any duplicated integers

    
private
 
static
 
boolean
 containsDuplicates
(
int
[]
 a
)
 
{

        
for
 
(
int
 i 
=
 
1
;
 i 
<  a . length ;  i ++ )              if   ( a [ i ]   ==  a [ i - 1 ])   return   true ;          return   false ;      }      /**      * Prints to standard output the (i, j, k) with { @code  i < j < k}      * such that { @code  a[i] + a[j] + a[k] == 0}.      *      *  @param  a the array of integers      *  @throws  IllegalArgumentException if the array contains duplicate integers      */      public   static   void  printAll ( int []  a )   {          int  n  =  a . length ;          Arrays . sort ( a );          if   ( containsDuplicates ( a ))   throw   new   IllegalArgumentException ( "array contains duplicate integers" );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  int  k  =   Arrays . binarySearch ( a ,   - ( a [ i ]   +  a [ j ]));                  if   ( k  >
 j
)
 
StdOut
.
println
(
a
[
i
]
 
+
 
” ”
 
+
 a
[
j
]
 
+
 
” ”
 
+
 a
[
k
]);

            
}

        
}

    
}
 

    
/**

     * Returns the number of triples (i, j, k) with {
@code
 i < j < k}      * such that { @code  a[i] + a[j] + a[k] == 0}.      *      *  @param  a the array of integers      *  @return  the number of triples (i, j, k) with { @code  i < j < k}      * such that { @code  a[i] + a[j] + a[k] == 0}      */      public   static   int  count ( int []  a )   {          int  n  =  a . length ;          Arrays . sort ( a );          if   ( containsDuplicates ( a ))   throw   new   IllegalArgumentException ( "array contains duplicate integers" );          int  count  =   0 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  int  k  =   Arrays . binarySearch ( a ,   - ( a [ i ]   +  a [ j ]));                  if   ( k  >
 j
)
 count
++
;

            
}

        
}

        
return
 count
;

    
}
 

    
/**

     * Reads in a sequence of distinct integers from a file, specified as a command-line argument;

     * counts the number of triples sum to exactly zero; prints out the time to perform

     * the computation.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
  
{
 

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
[]
 a 
=
 in
.
readAllInts
();

        
int
 count 
=
 count
(
a
);

        
StdOut
.
println
(
count
);

    
}
 

}
 

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/ThreeSum.java
edu/princeton/cs/algs4/ThreeSum.java
/******************************************************************************

 *  Compilation:  javac ThreeSum.java

 *  Execution:    java ThreeSum input.txt

 *  Dependencies: In.java StdOut.java Stopwatch.java

 *  Data files:   https://algs4.cs.princeton.edu/14analysis/1Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/2Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/4Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/8Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/16Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/32Kints.txt

 *                https://algs4.cs.princeton.edu/14analysis/1Mints.txt

 *

 *  A program with cubic running time. Reads n integers

 *  and counts the number of triples that sum to exactly 0

 *  (ignoring integer overflow).

 *

 *  % java ThreeSum 1Kints.txt 

 *  70

 *

 *  % java ThreeSum 2Kints.txt 

 *  528

 *

 *  % java ThreeSum 4Kints.txt 

 *  4039

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 ThreeSum} class provides static methods for counting

 *  and printing the number of triples in an array of integers that sum to 0

 *  (ignoring integer overflow).

 *  

 *  This implementation uses a triply nested loop and takes proportional to n^3,

 *  where n is the number of integers.

 *  

 *  For additional documentation, see Section 1.4 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
ThreeSum
 
{

    
// Do not instantiate.

    
private
 
ThreeSum
()
 
{
 
}

    
/**

     * Prints to standard output the (i, j, k) with {
@code
 i < j < k}      * such that { @code  a[i] + a[j] + a[k] == 0}.      *      *  @param  a the array of integers      */      public   static   void  printAll ( int []  a )   {          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  for   ( int  k  =  j + 1 ;  k  <  n ;  k ++ )   {                      if   ( a [ i ]   +  a [ j ]   +  a [ k ]   ==   0 )   {                          StdOut . println ( a [ i ]   +   " "   +  a [ j ]   +   " "   +  a [ k ]);                      }                  }              }          }      }        /**      * Returns the number of triples (i, j, k) with { @code  i < j < k}      * such that { @code  a[i] + a[j] + a[k] == 0}.      *      *  @param   a the array of integers      *  @return  the number of triples (i, j, k) with { @code  i < j < k}      *         such that { @code  a[i] + a[j] + a[k] == 0}      */      public   static   int  count ( int []  a )   {          int  n  =  a . length ;          int  count  =   0 ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {                  for   ( int  k  =  j + 1 ;  k  <  n ;  k ++ )   {                      if   ( a [ i ]   +  a [ j ]   +  a [ k ]   ==   0 )   {                         count ++ ;                      }                  }              }          }          return  count ;      }        /**      * Reads in a sequence of integers from a file, specified as a command-line argument;      * counts the number of triples sum to exactly zero; prints out the time to perform      * the computation.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )    {            In  in  =   new   In ( args [ 0 ]);          int []  a  =  in . readAllInts ();          Stopwatch  timer  =   new   Stopwatch ();          int  count  =  count ( a );          StdOut . println ( "elapsed time = "   +  timer . elapsedTime ());          StdOut . println ( count );      }   }   /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TopM.java edu/princeton/cs/algs4/TopM.java /******************************************************************************  *  Compilation:  javac TopM.java  *  Execution:    java TopM m < input.txt  *  Dependencies: MinPQ.java Transaction.java StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyBatch.txt  *   *  Given an integer m from the command line and an input stream where  *  each line contains a String and a long value, this MinPQ client  *  prints the m lines whose numbers are the highest.  *   *  % java TopM 5 < tinyBatch.txt   *  Thompson    2/27/2000  4747.08  *  vonNeumann  2/12/1994  4732.35  *  vonNeumann  1/11/1999  4409.74  *  Hoare       8/18/1992  4381.21  *  vonNeumann  3/26/2002  4121.85  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  TopM} class provides a client that reads a sequence of  *  transactions from standard input and prints the m largest ones

 *  to standard output. This implementation uses a {
@link
 MinPQ} of size

 *  at most m + 1 to identify the M largest transactions

 *  and a {
@link
 Stack} to output them in the proper order.

 *  

 *  For additional documentation, see Section 2.4

 *  of Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TopM
 
{
   

    
// This class should not be instantiated.

    
private
 
TopM
()
 
{
 
}

    
/**

     *  Reads a sequence of transactions from standard input; takes a

     *  command-line integer m; prints to standard output the m largest

     *  transactions in descending order.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 m 
=
 
Integer
.
parseInt
(
args
[
0
]);
 

        
MinPQ
< Transaction >
 pq 
=
 
new
 
MinPQ
< Transaction >
(
m
+
1
);

        
while
 
(
StdIn
.
hasNextLine
())
 
{

            
// Create an entry from the next line and put on the PQ. 

            
String
 line 
=
 
StdIn
.
readLine
();

            
Transaction
 transaction 
=
 
new
 
Transaction
(
line
);

            pq
.
insert
(
transaction
);
 

            
// remove minimum if m+1 entries on the PQ

            
if
 
(
pq
.
size
()
 
>
 m
)
 

                pq
.
delMin
();

        
}
   
// top m entries are on the PQ

        
// print entries on PQ in reverse order

        
Stack
< Transaction >
 stack 
=
 
new
 
Stack
< Transaction >
();

        
for
 
(
Transaction
 transaction 
:
 pq
)

            stack
.
push
(
transaction
);

        
for
 
(
Transaction
 transaction 
:
 stack
)

            
StdOut
.
println
(
transaction
);

    
}
 

}
 

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Topological.java
edu/princeton/cs/algs4/Topological.java
/******************************************************************************

 *  Compilation:  javac Topological.java

 *  Execution:    java  Topological filename.txt delimiter

 *  Dependencies: Digraph.java DepthFirstOrder.java DirectedCycle.java

 *                EdgeWeightedDigraph.java EdgeWeightedDirectedCycle.java

 *                SymbolDigraph.java

 *  Data files:   https://algs4.cs.princeton.edu/42digraph/jobs.txt

 *

 *  Compute topological ordering of a DAG or edge-weighted DAG.

 *  Runs in O(E + V) time.

 *

 *  % java Topological jobs.txt “/”

 *  Calculus

 *  Linear Algebra

 *  Introduction to CS

 *  Advanced Programming

 *  Algorithms

 *  Theoretical CS

 *  Artificial Intelligence

 *  Robotics

 *  Machine Learning

 *  Neural Networks

 *  Databases

 *  Scientific Computing

 *  Computational Biology

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Topological} class represents a data type for 

 *  determining a topological order of a directed acyclic graph (DAG).

 *  A digraph has a topological order if and only if it is a DAG.

 *  The hasOrder operation determines whether the digraph has

 *  a topological order, and if so, the order operation

 *  returns one.

 *  

 *  This implementation uses depth-first search.

 *  The constructor takes Θ(V + E) time in the

 *  worst case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  See {
@link
 DirectedCycle}, {
@link
 DirectedCycleX}, and

 *  {
@link
 EdgeWeightedDirectedCycle} for computing a directed cycle

 *  if the digraph is not a DAG.

 *  See {
@link
 TopologicalX} for a nonrecursive queue-based algorithm

 *  for computing a topological order of a DAG.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Topological
 
{

    
private
 
Iterable
< Integer >
 order
;
  
// topological order

    
private
 
int
[]
 rank
;
               
// rank[v] = rank of vertex v in order

    
/**

     * Determines whether the digraph {
@code
 G} has a topological order and, if so,

     * finds such a topological order.

     * 
@param
 G the digraph

     */

    
public
 
Topological
(
Digraph
 G
)
 
{

        
DirectedCycle
 finder 
=
 
new
 
DirectedCycle
(
G
);

        
if
 
(
!
finder
.
hasCycle
())
 
{

            
DepthFirstOrder
 dfs 
=
 
new
 
DepthFirstOrder
(
G
);

            order 
=
 dfs
.
reversePost
();

            rank 
=
 
new
 
int
[
G
.
V
()];

            
int
 i 
=
 
0
;

            
for
 
(
int
 v 
:
 order
)

                rank
[
v
]
 
=
 i
++
;

        
}

    
}

    
/**

     * Determines whether the edge-weighted digraph {
@code
 G} has a topological

     * order and, if so, finds such an order.

     * 
@param
 G the edge-weighted digraph

     */

    
public
 
Topological
(
EdgeWeightedDigraph
 G
)
 
{

        
EdgeWeightedDirectedCycle
 finder 
=
 
new
 
EdgeWeightedDirectedCycle
(
G
);

        
if
 
(
!
finder
.
hasCycle
())
 
{

            
DepthFirstOrder
 dfs 
=
 
new
 
DepthFirstOrder
(
G
);

            order 
=
 dfs
.
reversePost
();

        
}

    
}

    
/**

     * Returns a topological order if the digraph has a topologial order,

     * and {
@code
 null} otherwise.

     * 
@return
 a topological order of the vertices (as an interable) if the

     *    digraph has a topological order (or equivalently, if the digraph is a DAG),

     *    and {
@code
 null} otherwise

     */

    
public
 
Iterable
< Integer >
 order
()
 
{

        
return
 order
;

    
}

    
/**

     * Does the digraph have a topological order?

     * 
@return
 {
@code
 true} if the digraph has a topological order (or equivalently,

     *    if the digraph is a DAG), and {
@code
 false} otherwise

     */

    
public
 
boolean
 hasOrder
()
 
{

        
return
 order 
!=
 
null
;

    
}

    
/**

     * Does the digraph have a topological order?

     * 
@return
 {
@code
 true} if the digraph has a topological order (or equivalently,

     *    if the digraph is a DAG), and {
@code
 false} otherwise

     * 
@deprecated
 Replaced by {
@link
 #hasOrder()}.

     */

    @
Deprecated

    
public
 
boolean
 isDAG
()
 
{

        
return
 hasOrder
();

    
}

    
/**

     * The the rank of vertex {
@code
 v} in the topological order;

     * -1 if the digraph is not a DAG

     *

     * 
@param
 v the vertex

     * 
@return
 the position of vertex {
@code
 v} in a topological order

     *    of the digraph; -1 if the digraph is not a DAG

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  rank ( int  v )   {         validateVertex ( v );          if   ( hasOrder ())   return  rank [ v ];          else              return   - 1 ;      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  rank . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 Topological} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
String
 filename  
=
 args
[
0
];

        
String
 delimiter 
=
 args
[
1
];

        
SymbolDigraph
 sg 
=
 
new
 
SymbolDigraph
(
filename
,
 delimiter
);

        
Topological
 topological 
=
 
new
 
Topological
(
sg
.
digraph
());

        
for
 
(
int
 v 
:
 topological
.
order
())
 
{

            
StdOut
.
println
(
sg
.
nameOf
(
v
));

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/TopologicalX.java
edu/princeton/cs/algs4/TopologicalX.java
/******************************************************************************

 *  Compilation:  javac TopologicalX.java

 *  Execution:    java TopologicalX V E F

 *  Dependencies: Queue.java Digraph.java

 *

 *  Compute topological ordering of a DAG using queue-based algorithm.

 *  Runs in O(E + V) time.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 TopologicalX} class represents a data type for 

 *  determining a topological order of a directed acyclic graph (DAG).

 *  A digraph has a topological order if and only if it is a DAG.

 *  The hasOrder operation determines whether the digraph has

 *  a topological order, and if so, the order operation

 *  returns one.

 *  

 *  This implementation uses a nonrecursive, queue-based algorithm.

 *  The constructor takes Θ(V + E) time in the worst

 *  case, where V is the number of vertices and E

 *  is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V) extra space (not including the digraph).

 *  

 *  See {
@link
 DirectedCycle}, {
@link
 DirectedCycleX}, and

 *  {
@link
 EdgeWeightedDirectedCycle} to compute a

 *  directed cycle if the digraph is not a DAG.

 *  See {
@link
 Topological} for a recursive version that uses depth-first search.

 *  

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TopologicalX
 
{

    
private
 
Queue
< Integer >
 order
;
     
// vertices in topological order

    
private
 
int
[]
 ranks
;
              
// ranks[v] = order where vertex v appers in order

    
/**

     * Determines whether the digraph {
@code
 G} has a topological order and, if so,

     * finds such a topological order.

     * 
@param
 G the digraph

     */

    
public
 
TopologicalX
(
Digraph
 G
)
 
{

        
// indegrees of remaining vertices

        
int
[]
 indegree 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             indegree [ v ]   =  G . indegree ( v );          }          // initialize          ranks  =   new   int [ G . V ()];           order  =   new   Queue < Integer >
();

        
int
 count 
=
 
0
;

        
// initialize queue to contain all vertices with indegree = 0

        
Queue
< Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );          while   ( ! queue . isEmpty ())   {              int  v  =  queue . dequeue ();             order . enqueue ( v );             ranks [ v ]   =  count ++ ;              for   ( int  w  :  G . adj ( v ))   {                 indegree [ w ] -- ;                  if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );              }          }          // there is a directed cycle in subgraph of vertices with indegree >= 1.

        
if
 
(
count 
!=
 G
.
V
())
 
{

            order 
=
 
null
;

        
}

        
assert
 check
(
G
);

    
}

    
/**

     * Determines whether the edge-weighted digraph {
@code
 G} has a

     * topological order and, if so, finds such a topological order.

     * 
@param
 G the digraph

     */

    
public
 
TopologicalX
(
EdgeWeightedDigraph
 G
)
 
{

        
// indegrees of remaining vertices

        
int
[]
 indegree 
=
 
new
 
int
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )   {             indegree [ v ]   =  G . indegree ( v );          }          // initialize          ranks  =   new   int [ G . V ()];           order  =   new   Queue < Integer >
();

        
int
 count 
=
 
0
;

        
// initialize queue to contain all vertices with indegree = 0

        
Queue
< Integer >
 queue 
=
 
new
 
Queue
< Integer >
();

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );          while   ( ! queue . isEmpty ())   {              int  v  =  queue . dequeue ();             order . enqueue ( v );             ranks [ v ]   =  count ++ ;              for   ( DirectedEdge  e  :  G . adj ( v ))   {                  int  w  =  e . to ();                 indegree [ w ] -- ;                  if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );              }          }          // there is a directed cycle in subgraph of vertices with indegree >= 1.

        
if
 
(
count 
!=
 G
.
V
())
 
{

            order 
=
 
null
;

        
}

        
assert
 check
(
G
);

    
}

    
/**

     * Returns a topological order if the digraph has a topologial order,

     * and {
@code
 null} otherwise.

     * 
@return
 a topological order of the vertices (as an interable) if the

     *    digraph has a topological order (or equivalently, if the digraph is a DAG),

     *    and {
@code
 null} otherwise

     */

    
public
 
Iterable
< Integer >
 order
()
 
{

        
return
 order
;

    
}

    
/**

     * Does the digraph have a topological order?

     * 
@return
 {
@code
 true} if the digraph has a topological order (or equivalently,

     *    if the digraph is a DAG), and {
@code
 false} otherwise

     */

    
public
 
boolean
 hasOrder
()
 
{

        
return
 order 
!=
 
null
;

    
}

    
/**

     * The the rank of vertex {
@code
 v} in the topological order;

     * -1 if the digraph is not a DAG

     *

     * 
@param
 v vertex

     * 
@return
 the position of vertex {
@code
 v} in a topological order

     *    of the digraph; -1 if the digraph is not a DAG

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= v < V}      */      public   int  rank ( int  v )   {         validateVertex ( v );          if   ( hasOrder ())   return  ranks [ v ];          else              return   - 1 ;      }      // certify that digraph is acyclic      private   boolean  check ( Digraph  G )   {          // digraph is acyclic          if   ( hasOrder ())   {              // check that ranks are a permutation of 0 to V-1              boolean []  found  =   new   boolean [ G . V ()];              for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {                 found [ rank ( i )]   =   true ;              }              for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {                  if   ( ! found [ i ])   {                      System . err . println ( "No vertex with rank "   +  i );                      return   false ;                  }              }              // check that ranks provide a valid topological order              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  for   ( int  w  :  G . adj ( v ))   {                      if   ( rank ( v )   >
 rank
(
w
))
 
{

                        
System
.
err
.
printf
(
“%d-%d: rank(%d) = %d, rank(%d) = %d\n”
,

                                          v
,
 w
,
 v
,
 rank
(
v
),
 w
,
 rank
(
w
));

                        
return
 
false
;

                    
}

                
}

            
}

            
// check that order() is consistent with rank()

            
int
 r 
=
 
0
;

            
for
 
(
int
 v 
:
 order
())
 
{

                
if
 
(
rank
(
v
)
 
!=
 r
)
 
{

                    
System
.
err
.
println
(
“order() and rank() inconsistent”
);

                    
return
 
false
;

                
}

                r
++
;

            
}

        
}

        
return
 
true
;

    
}

    
// certify that digraph is acyclic

    
private
 
boolean
 check
(
EdgeWeightedDigraph
 G
)
 
{

        
// digraph is acyclic

        
if
 
(
hasOrder
())
 
{

            
// check that ranks are a permutation of 0 to V-1

            
boolean
[]
 found 
=
 
new
 
boolean
[
G
.
V
()];

            
for
 
(
int
 i 
=
 
0
;
 i 
<  G . V ();  i ++ )   {                 found [ rank ( i )]   =   true ;              }              for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {                  if   ( ! found [ i ])   {                      System . err . println ( "No vertex with rank "   +  i );                      return   false ;                  }              }              // check that ranks provide a valid topological order              for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {                  for   ( DirectedEdge  e  :  G . adj ( v ))   {                      int  w  =  e . to ();                      if   ( rank ( v )   >
 rank
(
w
))
 
{

                        
System
.
err
.
printf
(
“%d-%d: rank(%d) = %d, rank(%d) = %d\n”
,

                                          v
,
 w
,
 v
,
 rank
(
v
),
 w
,
 rank
(
w
));

                        
return
 
false
;

                    
}

                
}

            
}

            
// check that order() is consistent with rank()

            
int
 r 
=
 
0
;

            
for
 
(
int
 v 
:
 order
())
 
{

                
if
 
(
rank
(
v
)
 
!=
 r
)
 
{

                    
System
.
err
.
println
(
“order() and rank() inconsistent”
);

                    
return
 
false
;

                
}

                r
++
;

            
}

        
}

        
return
 
true
;

    
}

    
// throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  ranks . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 TopologicalX} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// create random DAG with V vertices and E edges; then add F random edges

        
int
 V 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 E 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
int
 F 
=
 
Integer
.
parseInt
(
args
[
2
]);

        
Digraph
 G1 
=
 
DigraphGenerator
.
dag
(
V
,
 E
);

        
// corresponding edge-weighted digraph

        
EdgeWeightedDigraph
 G2 
=
 
new
 
EdgeWeightedDigraph
(
V
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G1 . V ();  v ++ )              for   ( int  w  :  G1 . adj ( v ))                 G2 . addEdge ( new   DirectedEdge ( v ,  w ,   0.0 ));          // add F extra edges          for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {              int  v  =   StdRandom . uniform ( V );              int  w  =   StdRandom . uniform ( V );             G1 . addEdge ( v ,  w );             G2 . addEdge ( new   DirectedEdge ( v ,  w ,   0.0 ));          }          StdOut . println ( G1 );          StdOut . println ();          StdOut . println ( G2 );          // find a directed cycle          TopologicalX  topological1  =   new   TopologicalX ( G1 );          if   ( ! topological1 . hasOrder ())   {              StdOut . println ( "Not a DAG" );          }          // or give topologial sort          else   {              StdOut . print ( "Topological order: " );              for   ( int  v  :  topological1 . order ())   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }          // find a directed cycle          TopologicalX  topological2  =   new   TopologicalX ( G2 );          if   ( ! topological2 . hasOrder ())   {              StdOut . println ( "Not a DAG" );          }          // or give topologial sort          else   {              StdOut . print ( "Topological order: " );              for   ( int  v  :  topological2 . order ())   {                  StdOut . print ( v  +   " " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/Transaction.java edu/princeton/cs/algs4/Transaction.java /******************************************************************************  *  Compilation:  javac Transaction.java  *  Execution:    java Transaction  *  Dependencies: StdOut.java  *    *  Data type for commercial transactions.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Arrays ; import  java . util . Comparator ; /**  *  The { @code  Transaction} class is an immutable data type to encapsulate a  *  commercial transaction with a customer name, date, and amount.  *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Transaction
 
implements
 
Comparable
< Transaction >
 
{

    
private
 
final
 
String
  who
;
      
// customer

    
private
 
final
 
Date
    when
;
     
// date

    
private
 
final
 
double
  amount
;
   
// amount

    
/**

     * Initializes a new transaction from the given arguments.

     *

     * 
@param
  who the person involved in this transaction

     * 
@param
  when the date of this transaction

     * 
@param
  amount the amount of this transaction

     * 
@throws
 IllegalArgumentException if {
@code
 amount} 

     *         is {
@code
 Double.NaN}, {
@code
 Double.POSITIVE_INFINITY},

     *         or {
@code
 Double.NEGATIVE_INFINITY}

     */

    
public
 
Transaction
(
String
 who
,
 
Date
 when
,
 
double
 amount
)
 
{

        
if
 
(
Double
.
isNaN
(
amount
)
 
||
 
Double
.
isInfinite
(
amount
))

            
throw
 
new
 
IllegalArgumentException
(
“Amount cannot be NaN or infinite”
);

        
this
.
who    
=
 who
;

        
this
.
when   
=
 when
;

        
this
.
amount 
=
 amount
;

    
}

    
/**

     * Initializes a new transaction by parsing a string of the form NAME DATE AMOUNT.

     *

     * 
@param
  transaction the string to parse

     * 
@throws
 IllegalArgumentException if {
@code
 amount} 

     *         is {
@code
 Double.NaN}, {
@code
 Double.POSITIVE_INFINITY},

     *         or {
@code
 Double.NEGATIVE_INFINITY}

     */

    
public
 
Transaction
(
String
 transaction
)
 
{

        
String
[]
 a 
=
 transaction
.
split
(
“\\s+”
);

        who    
=
 a
[
0
];

        when   
=
 
new
 
Date
(
a
[
1
]);

        amount 
=
 
Double
.
parseDouble
(
a
[
2
]);

        
if
 
(
Double
.
isNaN
(
amount
)
 
||
 
Double
.
isInfinite
(
amount
))

            
throw
 
new
 
IllegalArgumentException
(
“Amount cannot be NaN or infinite”
);

    
}

    
/**

     * Returns the name of the customer involved in this transaction.

     *

     * 
@return
 the name of the customer involved in this transaction

     */

    
public
 
String
 who
()
 
{

        
return
 who
;

    
}

 

    
/**

     * Returns the date of this transaction.

     *

     * 
@return
 the date of this transaction

     */

    
public
 
Date
 when
()
 
{

        
return
 when
;

    
}

 

    
/**

     * Returns the amount of this transaction.

     *

     * 
@return
 the amount of this transaction

     */

    
public
 
double
 amount
()
 
{

        
return
 amount
;

    
}

    
/**

     * Returns a string representation of this transaction.

     *

     * 
@return
 a string representation of this transaction

     */

    @
Override

    
public
 
String
 toString
()
 
{

        
return
 
String
.
format
(
“%-10s %10s %8.2f”
,
 who
,
 when
,
 amount
);

    
}

    
/**

     * Compares two transactions by amount.

     *

     * 
@param
  that the other transaction

     * 
@return
 { a negative integer, zero, a positive integer}, depending

     *         on whether the amount of this transaction is { less than,

     *         equal to, or greater than } the amount of that transaction

     */

    
public
 
int
 compareTo
(
Transaction
 that
)
 
{

        
return
 
Double
.
compare
(
this
.
amount
,
 that
.
amount
);

    
}
    

    
/**

     * Compares this transaction to the specified object.

     *

     * 
@param
  other the other transaction

     * 
@return
 true if this transaction is equal to {
@code
 other}; false otherwise

     */

    @
Override

    
public
 
boolean
 equals
(
Object
 other
)
 
{

        
if
 
(
other 
==
 
this
)
 
return
 
true
;

        
if
 
(
other 
==
 
null
)
 
return
 
false
;

        
if
 
(
other
.
getClass
()
 
!=
 
this
.
getClass
())
 
return
 
false
;

        
Transaction
 that 
=
 
(
Transaction
)
 other
;

        
return
 
(
this
.
amount 
==
 that
.
amount
)
 
&&
 
(
this
.
who
.
equals
(
that
.
who
))

                                            
&&
 
(
this
.
when
.
equals
(
that
.
when
));

    
}

    
/**

     * Returns a hash code for this transaction.

     *

     * 
@return
 a hash code for this transaction

     */

    
public
 
int
 hashCode
()
 
{

        
int
 hash 
=
 
1
;

        hash 
=
 
31
*
hash 
+
 who
.
hashCode
();

        hash 
=
 
31
*
hash 
+
 when
.
hashCode
();

        hash 
=
 
31
*
hash 
+
 
((
Double
)
 amount
).
hashCode
();

        
return
 hash
;

        
// return Objects.hash(who, when, amount);

    
}

    
/**

     * Compares two transactions by customer name.

     */

    
public
 
static
 
class
 
WhoOrder
 
implements
 
Comparator
< Transaction >
 
{

        @
Override

        
public
 
int
 compare
(
Transaction
 v
,
 
Transaction
 w
)
 
{

            
return
 v
.
who
.
compareTo
(
w
.
who
);

        
}

    
}

    
/**

     * Compares two transactions by date.

     */

    
public
 
static
 
class
 
WhenOrder
 
implements
 
Comparator
< Transaction >
 
{

        @
Override

        
public
 
int
 compare
(
Transaction
 v
,
 
Transaction
 w
)
 
{

            
return
 v
.
when
.
compareTo
(
w
.
when
);

        
}

    
}

    
/**

     * Compares two transactions by amount.

     */

    
public
 
static
 
class
 
HowMuchOrder
 
implements
 
Comparator
< Transaction >
 
{

        @
Override

        
public
 
int
 compare
(
Transaction
 v
,
 
Transaction
 w
)
 
{

            
return
 
Double
.
compare
(
v
.
amount
,
 w
.
amount
);

        
}

    
}

    
/**

     * Unit tests the {
@code
 Transaction} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Transaction
[]
 a 
=
 
new
 
Transaction
[
4
];

        a
[
0
]
 
=
 
new
 
Transaction
(
“Turing   6/17/1990  644.08”
);

        a
[
1
]
 
=
 
new
 
Transaction
(
“Tarjan   3/26/2002 4121.85”
);

        a
[
2
]
 
=
 
new
 
Transaction
(
“Knuth    6/14/1999  288.34”
);

        a
[
3
]
 
=
 
new
 
Transaction
(
“Dijkstra 8/22/2007 2678.40”
);

        
StdOut
.
println
(
“Unsorted”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )              StdOut . println ( a [ i ]);          StdOut . println ();                   StdOut . println ( "Sort by date" );          Arrays . sort ( a ,   new   Transaction . WhenOrder ());          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )              StdOut . println ( a [ i ]);          StdOut . println ();          StdOut . println ( "Sort by customer" );          Arrays . sort ( a ,   new   Transaction . WhoOrder ());          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )              StdOut . println ( a [ i ]);          StdOut . println ();          StdOut . println ( "Sort by amount" );          Arrays . sort ( a ,   new   Transaction . HowMuchOrder ());          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )              StdOut . println ( a [ i ]);          StdOut . println ();      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TransitiveClosure.java edu/princeton/cs/algs4/TransitiveClosure.java /******************************************************************************  *  Compilation:  javac TransitiveClosure.java  *  Execution:    java TransitiveClosure filename.txt  *  Dependencies: Digraph.java DepthFirstDirectedPaths.java In.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt  *  *  Compute transitive closure of a digraph and support  *  reachability queries.  *  *  Preprocessing time: O(V(E + V)) time.  *  Query time: O(1).  *  Space: O(V^2).  *  *  % java TransitiveClosure tinyDG.txt  *         0  1  2  3  4  5  6  7  8  9 10 11 12  *  --------------------------------------------  *    0:   T  T  T  T  T  T                       *    1:      T                                   *    2:   T  T  T  T  T  T                       *    3:   T  T  T  T  T  T                       *    4:   T  T  T  T  T  T                       *    5:   T  T  T  T  T  T                       *    6:   T  T  T  T  T  T  T        T  T  T  T  *    7:   T  T  T  T  T  T  T  T  T  T  T  T  T  *    8:   T  T  T  T  T  T  T  T  T  T  T  T  T  *    9:   T  T  T  T  T  T           T  T  T  T  *   10:   T  T  T  T  T  T           T  T  T  T  *   11:   T  T  T  T  T  T           T  T  T  T  *   12:   T  T  T  T  T  T           T  T  T  T  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  TransitiveClosure} class represents a data type for   *  computing the transitive closure of a digraph.  *  

 *  This implementation runs depth-first search from each vertex.

 *  The constructor takes Θ(V(V + E))

 *  in the worst case, where V is the number of vertices and

 *  E is the number of edges.

 *  Each instance method takes Θ(1) time.

 *  It uses Θ(V2) extra space (not including the digraph).

 *  

 *  For large digraphs, you may want to consider a more sophisticated algorithm.

 *  Nuutila proposes two

 *  algorithm for the problem (based on strong components and an interval representation)

 *  that runs in Θ(E + V) time on typical digraphs.

 *

 *  For additional documentation,

 *  see Section 4.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TransitiveClosure
 
{

    
private
 
DirectedDFS
[]
 tc
;
  
// tc[v] = reachable from v

    
/**

     * Computes the transitive closure of the digraph {
@code
 G}.

     * 
@param
 G the digraph

     */

    
public
 
TransitiveClosure
(
Digraph
 G
)
 
{

        tc 
=
 
new
 
DirectedDFS
[
G
.
V
()];

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )             tc [ v ]   =   new   DirectedDFS ( G ,  v );      }      /**      * Is there a directed path from vertex { @code  v} to vertex { @code  w} in the digraph?      *  @param   v the source vertex      *  @param   w the target vertex      *  @return  { @code  true} if there is a directed path from { @code  v} to { @code  w},      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless { @code  0 <= v < V}      *  @throws  IllegalArgumentException unless { @code  0 <= w < V}      */      public   boolean  reachable ( int  v ,   int  w )   {         validateVertex ( v );         validateVertex ( w );          return  tc [ v ]. marked ( w );      }      // throw an IllegalArgumentException unless {@code 0 <= v < V}      private   void  validateVertex ( int  v )   {          int  V  =  tc . length ;          if   ( v  <   0   ||  v  >=
 V
)

            
throw
 
new
 
IllegalArgumentException
(
“vertex ”
 
+
 v 
+
 
” is not between 0 and ”
 
+
 
(
V

1
));

    
}

    
/**

     * Unit tests the {
@code
 TransitiveClosure} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
Digraph
 G 
=
 
new
 
Digraph
(
in
);

        
TransitiveClosure
 tc 
=
 
new
 
TransitiveClosure
(
G
);

        
// print header

        
StdOut
.
print
(
”     ”
);

        
for
 
(
int
 v 
=
 
0
;
 v 
<  G . V ();  v ++ )              StdOut . printf ( "%3d" ,  v );          StdOut . println ();          StdOut . println ( "--------------------------------------------" );          // print transitive closure          for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {              StdOut . printf ( "%3d: " ,  v );              for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {                  if   ( tc . reachable ( v ,  w ))   StdOut . printf ( "  T" );                  else                      StdOut . printf ( "   " );              }              StdOut . println ();          }      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TrieSET.java edu/princeton/cs/algs4/TrieSET.java /******************************************************************************  *  Compilation:  javac TrieSET.java  *  Execution:    java TrieSET < words.txt  *  Dependencies: StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt  *  *  An set for extended ASCII strings, implemented  using a 256-way trie.  *  *  Sample client reads in a list of words from standard input and  *  prints out each word, removing any duplicates.  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; import  java . util . Iterator ; /**  *  The { @code  TrieSET} class represents an ordered set of strings over  *  the extended ASCII alphabet.  *  It supports the usual addcontains, and delete

 *  methods. It also provides character-based methods for finding the string

 *  in the set that is the longest prefix of a given prefix,

 *  finding all strings in the set that start with a given prefix,

 *  and finding all strings in the set that match a given pattern.

 *  

 *  This implementation uses a 256-way trie.

 *  The addcontainsdelete, and

 *  longest prefix methods take time proportional to the length

 *  of the key (in the worst case). Construction takes constant time.

 *  

 *  For additional documentation, see

 *  Section 5.2 of

 *  Algorithms in Java, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TrieSET
 
implements
 
Iterable
< String >
 
{

    
private
 
static
 
final
 
int
 R 
=
 
256
;
        
// extended ASCII

    
private
 
Node
 root
;
      
// root of trie

    
private
 
int
 n
;
          
// number of keys in trie

    
// R-way trie node

    
private
 
static
 
class
 
Node
 
{

        
private
 
Node
[]
 next 
=
 
new
 
Node
[
R
];

        
private
 
boolean
 isString
;

    
}

    
/**

     * Initializes an empty set of strings.

     */

    
public
 
TrieSET
()
 
{

    
}

    
/**

     * Does the set contain the given key?

     * 
@param
 key the key

     * 
@return
 {
@code
 true} if the set contains {
@code
 key} and

     *     {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
Node
 x 
=
 get
(
root
,
 key
,
 
0
);

        
if
 
(

==
 
null
)
 
return
 
false
;

        
return
 x
.
isString
;

    
}

    
private
 
Node
 get
(
Node
 x
,
 
String
 key
,
 
int
 d
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
if
 
(

==
 key
.
length
())
 
return
 x
;

        
char
 c 
=
 key
.
charAt
(
d
);

        
return
 get
(
x
.
next
[
c
],
 key
,
 d
+
1
);

    
}

    
/**

     * Adds the key to the set if it is not already present.

     * 
@param
 key the key to add

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 add
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to add() is null”
);

        root 
=
 add
(
root
,
 key
,
 
0
);

    
}

    
private
 
Node
 add
(
Node
 x
,
 
String
 key
,
 
int
 d
)
 
{

        
if
 
(

==
 
null
)
 x 
=
 
new
 
Node
();

        
if
 
(

==
 key
.
length
())
 
{

            
if
 
(
!
x
.
isString
)
 n
++
;

            x
.
isString 
=
 
true
;

        
}

        
else
 
{

            
char
 c 
=
 key
.
charAt
(
d
);

            x
.
next
[
c
]
 
=
 add
(
x
.
next
[
c
],
 key
,
 d
+
1
);

        
}

        
return
 x
;

    
}

    
/**

     * Returns the number of strings in the set.

     * 
@return
 the number of strings in the set

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Is the set empty?

     * 
@return
 {
@code
 true} if the set is empty, and {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns all of the keys in the set, as an iterator.

     * To iterate over all of the keys in a set named {
@code
 set}, use the

     * foreach notation: {
@code
 for (Key key : set)}.

     * 
@return
 an iterator to all of the keys in the set

     */

    
public
 
Iterator
< String >
 iterator
()
 
{

        
return
 keysWithPrefix
(
“”
).
iterator
();

    
}

    
/**

     * Returns all of the keys in the set that start with {
@code
 prefix}.

     * 
@param
 prefix the prefix

     * 
@return
 all of the keys in the set that start with {
@code
 prefix},

     *     as an iterable

     */

    
public
 
Iterable
< String >
 keysWithPrefix
(
String
 prefix
)
 
{

        
Queue
< String >
 results 
=
 
new
 
Queue
< String >
();

        
Node
 x 
=
 get
(
root
,
 prefix
,
 
0
);

        collect
(
x
,
 
new
 
StringBuilder
(
prefix
),
 results
);

        
return
 results
;

    
}

    
private
 
void
 collect
(
Node
 x
,
 
StringBuilder
 prefix
,
 
Queue
< String >
 results
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
if
 
(
x
.
isString
)
 results
.
enqueue
(
prefix
.
toString
());

        
for
 
(
char
 c 
=
 
0
;
 c 
<  R ;  c ++ )   {             prefix . append ( c );             collect ( x . next [ c ],  prefix ,  results );             prefix . deleteCharAt ( prefix . length ()   -   1 );          }      }      /**      * Returns all of the keys in the set that match { @code  pattern},      * where . symbol is treated as a wildcard character.      *  @param  pattern the pattern      *  @return  all of the keys in the set that match { @code  pattern},      *     as an iterable, where . is treated as a wildcard character.      */         public   Iterable < String >
 keysThatMatch
(
String
 pattern
)
 
{

        
Queue
< String >
 results 
=
 
new
 
Queue
< String >
();

        
StringBuilder
 prefix 
=
 
new
 
StringBuilder
();

        collect
(
root
,
 prefix
,
 pattern
,
 results
);

        
return
 results
;

    
}

        

    
private
 
void
 collect
(
Node
 x
,
 
StringBuilder
 prefix
,
 
String
 pattern
,
 
Queue
< String >
 results
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
int
 d 
=
 prefix
.
length
();

        
if
 
(

==
 pattern
.
length
()
 
&&
 x
.
isString
)

            results
.
enqueue
(
prefix
.
toString
());

        
if
 
(

==
 pattern
.
length
())

            
return
;

        
char
 c 
=
 pattern
.
charAt
(
d
);

        
if
 
(

==
 
‘.’
)
 
{

            
for
 
(
char
 ch 
=
 
0
;
 ch 
<  R ;  ch ++ )   {                 prefix . append ( ch );                 collect ( x . next [ ch ],  prefix ,  pattern ,  results );                 prefix . deleteCharAt ( prefix . length ()   -   1 );              }          }          else   {             prefix . append ( c );             collect ( x . next [ c ],  prefix ,  pattern ,  results );             prefix . deleteCharAt ( prefix . length ()   -   1 );          }      }      /**      * Returns the string in the set that is the longest prefix of { @code  query},      * or { @code  null}, if no such string.      *  @param  query the query string      *  @return  the string in the set that is the longest prefix of { @code  query},      *     or { @code  null} if no such string      *  @throws  IllegalArgumentException if { @code  query} is { @code  null}      */      public   String  longestPrefixOf ( String  query )   {          if   ( query  ==   null )   throw   new   IllegalArgumentException ( "argument to longestPrefixOf() is null" );          int  length  =  longestPrefixOf ( root ,  query ,   0 ,   - 1 );          if   ( length  ==   - 1 )   return   null ;          return  query . substring ( 0 ,  length );      }      // returns the length of the longest string key in the subtrie      // rooted at x that is a prefix of the query string,      // assuming the first d character match and we have already      // found a prefix match of length length      private   int  longestPrefixOf ( Node  x ,   String  query ,   int  d ,   int  length )   {          if   ( x  ==   null )   return  length ;          if   ( x . isString )  length  =  d ;          if   ( d  ==  query . length ())   return  length ;          char  c  =  query . charAt ( d );          return  longestPrefixOf ( x . next [ c ],  query ,  d + 1 ,  length );      }      /**      * Removes the key from the set if the key is present.      *  @param  key the key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  delete ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );         root  =  delete ( root ,  key ,   0 );      }      private   Node  delete ( Node  x ,   String  key ,   int  d )   {          if   ( x  ==   null )   return   null ;          if   ( d  ==  key . length ())   {              if   ( x . isString )  n -- ;             x . isString  =   false ;          }          else   {              char  c  =  key . charAt ( d );             x . next [ c ]   =  delete ( x . next [ c ],  key ,  d + 1 );          }          // remove subtrie rooted at x if it is completely empty          if   ( x . isString )   return  x ;          for   ( int  c  =   0 ;  c  <  R ;  c ++ )              if   ( x . next [ c ]   !=   null )                  return  x ;          return   null ;      }      /**      * Unit tests the { @code  TrieSET} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          TrieSET  set  =   new   TrieSET ();          while   ( ! StdIn . isEmpty ())   {              String  key  =   StdIn . readString ();             set . add ( key );          }          // print results          if   ( set . size ()   <   100 )   {              StdOut . println ( "keys(\"\"):" );              for   ( String  key  :  set )   {                  StdOut . println ( key );              }              StdOut . println ();          }          StdOut . println ( "longestPrefixOf(\"shellsort\"):" );          StdOut . println ( set . longestPrefixOf ( "shellsort" ));          StdOut . println ();          StdOut . println ( "longestPrefixOf(\"xshellsort\"):" );          StdOut . println ( set . longestPrefixOf ( "xshellsort" ));          StdOut . println ();          StdOut . println ( "keysWithPrefix(\"shor\"):" );          for   ( String  s  :  set . keysWithPrefix ( "shor" ))              StdOut . println ( s );          StdOut . println ();          StdOut . println ( "keysWithPrefix(\"shortening\"):" );          for   ( String  s  :  set . keysWithPrefix ( "shortening" ))              StdOut . println ( s );          StdOut . println ();          StdOut . println ( "keysThatMatch(\".he.l.\"):" );          for   ( String  s  :  set . keysThatMatch ( ".he.l." ))              StdOut . println ( s );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TrieST.java edu/princeton/cs/algs4/TrieST.java /******************************************************************************  *  Compilation:  javac TrieST.java  *  Execution:    java TrieST < words.txt  *  Dependencies: StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt  *  *  A string symbol table for extended ASCII strings, implemented  *  using a 256-way trie.  *  *  % java TrieST < shellsST.txt   *  by 4  *  sea 6  *  sells 1  *  she 0  *  shells 3  *  shore 7  *  the 5  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  TrieST} class represents an symbol table of key-value  *  pairs, with string keys and generic values.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides character-based methods for finding the string

 *  in the symbol table that is the longest prefix of a given prefix,

 *  finding all strings in the symbol table that start with a given prefix,

 *  and finding all strings in the symbol table that match a given pattern.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This implementation uses a 256-way trie.

 *  The putcontainsdelete, and

 *  longest prefix operations take time proportional to the length

 *  of the key (in the worst case). Construction takes constant time.

 *  The size, and is-empty operations take constant time.

 *  Construction takes constant time.

 *  

 *  For additional documentation, see Section 5.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 
TrieST
< Value >
 
{

    
private
 
static
 
final
 
int
 R 
=
 
256
;
        
// extended ASCII

    
private
 
Node
 root
;
      
// root of trie

    
private
 
int
 n
;
          
// number of keys in trie

    
// R-way trie node

    
private
 
static
 
class
 
Node
 
{

        
private
 
Object
 val
;

        
private
 
Node
[]
 next 
=
 
new
 
Node
[
R
];

    
}

   
/**

     * Initializes an empty string symbol table.

     */

    
public
 
TrieST
()
 
{

    
}

    
/**

     * Returns the value associated with the given key.

     * 
@param
 key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *     and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to get() is null”
);

        
Node
 x 
=
 get
(
root
,
 key
,
 
0
);

        
if
 
(

==
 
null
)
 
return
 
null
;

        
return
 
(
Value
)
 x
.
val
;

    
}

    
/**

     * Does this symbol table contain the given key?

     * 
@param
 key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key} and

     *     {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
private
 
Node
 get
(
Node
 x
,
 
String
 key
,
 
int
 d
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
if
 
(

==
 key
.
length
())
 
return
 x
;

        
char
 c 
=
 key
.
charAt
(
d
);

        
return
 get
(
x
.
next
[
c
],
 key
,
 d
+
1
);

    
}

    
/**

     * Inserts the key-value pair into the symbol table, overwriting the old value

     * with the new value if the key is already in the symbol table.

     * If the value is {
@code
 null}, this effectively deletes the key from the symbol table.

     * 
@param
 key the key

     * 
@param
 val the value

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
void
 put
(
String
 key
,
 
Value
 val
)
 
{

        
if
 
(
key 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“first argument to put() is null”
);

        
if
 
(
val 
==
 
null
)
 delete
(
key
);

        
else
 root 
=
 put
(
root
,
 key
,
 val
,
 
0
);

    
}

    
private
 
Node
 put
(
Node
 x
,
 
String
 key
,
 
Value
 val
,
 
int
 d
)
 
{

        
if
 
(

==
 
null
)
 x 
=
 
new
 
Node
();

        
if
 
(

==
 key
.
length
())
 
{

            
if
 
(
x
.
val 
==
 
null
)
 n
++
;

            x
.
val 
=
 val
;

            
return
 x
;

        
}

        
char
 c 
=
 key
.
charAt
(
d
);

        x
.
next
[
c
]
 
=
 put
(
x
.
next
[
c
],
 key
,
 val
,
 d
+
1
);

        
return
 x
;

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Is this symbol table empty?

     * 
@return
 {
@code
 true} if this symbol table is empty and {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 size
()
 
==
 
0
;

    
}

    
/**

     * Returns all keys in the symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     * 
@return
 all keys in the symbol table as an {
@code
 Iterable}

     */

    
public
 
Iterable
< String >
 keys
()
 
{

        
return
 keysWithPrefix
(
“”
);

    
}

    
/**

     * Returns all of the keys in the set that start with {
@code
 prefix}.

     * 
@param
 prefix the prefix

     * 
@return
 all of the keys in the set that start with {
@code
 prefix},

     *     as an iterable

     */

    
public
 
Iterable
< String >
 keysWithPrefix
(
String
 prefix
)
 
{

        
Queue
< String >
 results 
=
 
new
 
Queue
< String >
();

        
Node
 x 
=
 get
(
root
,
 prefix
,
 
0
);

        collect
(
x
,
 
new
 
StringBuilder
(
prefix
),
 results
);

        
return
 results
;

    
}

    
private
 
void
 collect
(
Node
 x
,
 
StringBuilder
 prefix
,
 
Queue
< String >
 results
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
if
 
(
x
.
val 
!=
 
null
)
 results
.
enqueue
(
prefix
.
toString
());

        
for
 
(
char
 c 
=
 
0
;
 c 
<  R ;  c ++ )   {             prefix . append ( c );             collect ( x . next [ c ],  prefix ,  results );             prefix . deleteCharAt ( prefix . length ()   -   1 );          }      }      /**      * Returns all of the keys in the symbol table that match { @code  pattern},      * where . symbol is treated as a wildcard character.      *  @param  pattern the pattern      *  @return  all of the keys in the symbol table that match { @code  pattern},      *     as an iterable, where . is treated as a wildcard character.      */      public   Iterable < String >
 keysThatMatch
(
String
 pattern
)
 
{

        
Queue
< String >
 results 
=
 
new
 
Queue
< String >
();

        collect
(
root
,
 
new
 
StringBuilder
(),
 pattern
,
 results
);

        
return
 results
;

    
}

    
private
 
void
 collect
(
Node
 x
,
 
StringBuilder
 prefix
,
 
String
 pattern
,
 
Queue
< String >
 results
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
int
 d 
=
 prefix
.
length
();

        
if
 
(

==
 pattern
.
length
()
 
&&
 x
.
val 
!=
 
null
)

            results
.
enqueue
(
prefix
.
toString
());

        
if
 
(

==
 pattern
.
length
())

            
return
;

        
char
 c 
=
 pattern
.
charAt
(
d
);

        
if
 
(

==
 
‘.’
)
 
{

            
for
 
(
char
 ch 
=
 
0
;
 ch 
<  R ;  ch ++ )   {                 prefix . append ( ch );                 collect ( x . next [ ch ],  prefix ,  pattern ,  results );                 prefix . deleteCharAt ( prefix . length ()   -   1 );              }          }          else   {             prefix . append ( c );             collect ( x . next [ c ],  prefix ,  pattern ,  results );             prefix . deleteCharAt ( prefix . length ()   -   1 );          }      }      /**      * Returns the string in the symbol table that is the longest prefix of { @code  query},      * or { @code  null}, if no such string.      *  @param  query the query string      *  @return  the string in the symbol table that is the longest prefix of { @code  query},      *     or { @code  null} if no such string      *  @throws  IllegalArgumentException if { @code  query} is { @code  null}      */      public   String  longestPrefixOf ( String  query )   {          if   ( query  ==   null )   throw   new   IllegalArgumentException ( "argument to longestPrefixOf() is null" );          int  length  =  longestPrefixOf ( root ,  query ,   0 ,   - 1 );          if   ( length  ==   - 1 )   return   null ;          else   return  query . substring ( 0 ,  length );      }      // returns the length of the longest string key in the subtrie      // rooted at x that is a prefix of the query string,      // assuming the first d character match and we have already      // found a prefix match of given length (-1 if no such match)      private   int  longestPrefixOf ( Node  x ,   String  query ,   int  d ,   int  length )   {          if   ( x  ==   null )   return  length ;          if   ( x . val  !=   null )  length  =  d ;          if   ( d  ==  query . length ())   return  length ;          char  c  =  query . charAt ( d );          return  longestPrefixOf ( x . next [ c ],  query ,  d + 1 ,  length );      }      /**      * Removes the key from the set if the key is present.      *  @param  key the key      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  delete ( String  key )   {          if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );         root  =  delete ( root ,  key ,   0 );      }      private   Node  delete ( Node  x ,   String  key ,   int  d )   {          if   ( x  ==   null )   return   null ;          if   ( d  ==  key . length ())   {              if   ( x . val  !=   null )  n -- ;             x . val  =   null ;          }          else   {              char  c  =  key . charAt ( d );             x . next [ c ]   =  delete ( x . next [ c ],  key ,  d + 1 );          }          // remove subtrie rooted at x if it is completely empty          if   ( x . val  !=   null )   return  x ;          for   ( int  c  =   0 ;  c  <  R ;  c ++ )              if   ( x . next [ c ]   !=   null )                  return  x ;          return   null ;      }      /**      * Unit tests the { @code  TrieST} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // build symbol table from standard input          TrieST < Integer >
 st 
=
 
new
 
TrieST
< Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
// print results

        
if
 
(
st
.
size
()
 
<   100 )   {              StdOut . println ( "keys(\"\"):" );              for   ( String  key  :  st . keys ())   {                  StdOut . println ( key  +   " "   +  st . get ( key ));              }              StdOut . println ();          }          StdOut . println ( "longestPrefixOf(\"shellsort\"):" );          StdOut . println ( st . longestPrefixOf ( "shellsort" ));          StdOut . println ();          StdOut . println ( "longestPrefixOf(\"quicksort\"):" );          StdOut . println ( st . longestPrefixOf ( "quicksort" ));          StdOut . println ();          StdOut . println ( "keysWithPrefix(\"shor\"):" );          for   ( String  s  :  st . keysWithPrefix ( "shor" ))              StdOut . println ( s );          StdOut . println ();          StdOut . println ( "keysThatMatch(\".he.l.\"):" );          for   ( String  s  :  st . keysThatMatch ( ".he.l." ))              StdOut . println ( s );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TST.java edu/princeton/cs/algs4/TST.java /******************************************************************************  *  Compilation:  javac TST.java  *  Execution:    java TST < words.txt  *  Dependencies: StdIn.java  *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt  *  *  Symbol table with string keys, implemented using a ternary search  *  trie (TST).  *  *  *  % java TST < shellsST.txt  *  keys(""):  *  by 4  *  sea 6  *  sells 1  *  she 0  *  shells 3  *  shore 7  *  the 5  *  *  longestPrefixOf("shellsort"):  *  shells  *  *  keysWithPrefix("shor"):  *  shore  *  *  keysThatMatch(".he.l."):  *  shells  *  *  % java TST  *  theory the now is the time for all good men  *  *  Remarks  *  --------  *    - can't use a key that is the empty string ""  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  TST} class represents an symbol table of key-value  *  pairs, with string keys and generic values.  *  It supports the usual putgetcontains,

 *  deletesize, and is-empty methods.

 *  It also provides character-based methods for finding the string

 *  in the symbol table that is the longest prefix of a given prefix,

 *  finding all strings in the symbol table that start with a given prefix,

 *  and finding all strings in the symbol table that match a given pattern.

 *  A symbol table implements the associative array abstraction:

 *  when associating a value with a key that is already in the symbol table,

 *  the convention is to replace the old value with the new value.

 *  Unlike {
@link
 java.util.Map}, this class uses the convention that

 *  values cannot be {
@code
 null}—setting the

 *  value associated with a key to {
@code
 null} is equivalent to deleting the key

 *  from the symbol table.

 *  

 *  This implementation uses a ternary search trie.

 *  

 *  For additional documentation, see Section 5.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 */

public
 
class
 TST
< Value >
 
{

    
private
 
int
 n
;
              
// size

    
private
 
Node
< Value >
 root
;
   
// root of TST

    
private
 
static
 
class
 
Node
< Value >
 
{

        
private
 
char
 c
;
                        
// character

        
private
 
Node
< Value >
 left
,
 mid
,
 right
;
  
// left, middle, and right subtries

        
private
 
Value
 val
;
                     
// value associated with string

    
}

    
/**

     * Initializes an empty string symbol table.

     */

    
public
 TST
()
 
{

    
}

    
/**

     * Returns the number of key-value pairs in this symbol table.

     * 
@return
 the number of key-value pairs in this symbol table

     */

    
public
 
int
 size
()
 
{

        
return
 n
;

    
}

    
/**

     * Does this symbol table contain the given key?

     * 
@param
 key the key

     * 
@return
 {
@code
 true} if this symbol table contains {
@code
 key} and

     *     {
@code
 false} otherwise

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
boolean
 contains
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“argument to contains() is null”
);

        
}

        
return
 get
(
key
)
 
!=
 
null
;

    
}

    
/**

     * Returns the value associated with the given key.

     * 
@param
 key the key

     * 
@return
 the value associated with the given key if the key is in the symbol table

     *     and {
@code
 null} if the key is not in the symbol table

     * 
@throws
 IllegalArgumentException if {
@code
 key} is {
@code
 null}

     */

    
public
 
Value
 get
(
String
 key
)
 
{

        
if
 
(
key 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“calls get() with null argument”
);

        
}

        
if
 
(
key
.
length
()
 
==
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“key must have length >= 1”
);

        
Node
< Value >
 x 
=
 get
(
root
,
 key
,
 
0
);

        
if
 
(

==
 
null
)
 
return
 
null
;

        
return
 x
.
val
;

    
}

    
// return subtrie corresponding to given key

    
private
 
Node
< Value >
 get
(
Node
< Value >
 x
,
 
String
 key
,
 
int
 d
)
 
{

        
if
 
(

==
 
null
)
 
return
 
null
;

        
if
 
(
key
.
length
()
 
==
 
0
)
 
throw
 
new
 
IllegalArgumentException
(
“key must have length >= 1”
);

        
char
 c 
=
 key
.
charAt
(
d
);

        
if
      
(

<  x . c )                return  get ( x . left ,   key ,  d );          else   if   ( c  >
 x
.
c
)
              
return
 get
(
x
.
right
,
 key
,
 d
);

        
else
 
if
 
(

<  key . length ()   -   1 )   return  get ( x . mid ,    key ,  d + 1 );          else                             return  x ;      }      /**      * Inserts the key-value pair into the symbol table, overwriting the old value      * with the new value if the key is already in the symbol table.      * If the value is { @code  null}, this effectively deletes the key from the symbol table.      *  @param  key the key      *  @param  val the value      *  @throws  IllegalArgumentException if { @code  key} is { @code  null}      */      public   void  put ( String  key ,   Value  val )   {          if   ( key  ==   null )   {              throw   new   IllegalArgumentException ( "calls put() with null key" );          }          if   ( ! contains ( key ))  n ++ ;          else   if ( val  ==   null )  n -- ;         // delete existing key         root  =  put ( root ,  key ,  val ,   0 );      }      private   Node < Value >
 put
(
Node
< Value >
 x
,
 
String
 key
,
 
Value
 val
,
 
int
 d
)
 
{

        
char
 c 
=
 key
.
charAt
(
d
);

        
if
 
(

==
 
null
)
 
{

            x 
=
 
new
 
Node
< Value >
();

            x
.

=
 c
;

        
}

        
if
      
(

<  x . c )                x . left   =  put ( x . left ,   key ,  val ,  d );          else   if   ( c  >
 x
.
c
)
               x
.
right 
=
 put
(
x
.
right
,
 key
,
 val
,
 d
);

        
else
 
if
 
(

<  key . length ()   -   1 )   x . mid    =  put ( x . mid ,    key ,  val ,  d + 1 );          else                             x . val    =  val ;          return  x ;      }      /**      * Returns the string in the symbol table that is the longest prefix of { @code  query},      * or { @code  null}, if no such string.      *  @param  query the query string      *  @return  the string in the symbol table that is the longest prefix of { @code  query},      *     or { @code  null} if no such string      *  @throws  IllegalArgumentException if { @code  query} is { @code  null}      */      public   String  longestPrefixOf ( String  query )   {          if   ( query  ==   null )   {              throw   new   IllegalArgumentException ( "calls longestPrefixOf() with null argument" );          }          if   ( query . length ()   ==   0 )   return   null ;          int  length  =   0 ;          Node < Value >
 x 
=
 root
;

        
int
 i 
=
 
0
;

        
while
 
(

!=
 
null
 
&&
 i 
<  query . length ())   {              char  c  =  query . charAt ( i );              if        ( c  <  x . c )  x  =  x . left ;              else   if   ( c  >
 x
.
c
)
 x 
=
 x
.
right
;

            
else
 
{

                i
++
;

                
if
 
(
x
.
val 
!=
 
null
)
 length 
=
 i
;

                x 
=
 x
.
mid
;

            
}

        
}

        
return
 query
.
substring
(
0
,
 length
);

    
}

    
/**

     * Returns all keys in the symbol table as an {
@code
 Iterable}.

     * To iterate over all of the keys in the symbol table named {
@code
 st},

     * use the foreach notation: {
@code
 for (Key key : st.keys())}.

     * 
@return
 all keys in the symbol table as an {
@code
 Iterable}

     */

    
public
 
Iterable
< String >
 keys
()
 
{

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        collect
(
root
,
 
new
 
StringBuilder
(),
 queue
);

        
return
 queue
;

    
}

    
/**

     * Returns all of the keys in the set that start with {
@code
 prefix}.

     * 
@param
 prefix the prefix

     * 
@return
 all of the keys in the set that start with {
@code
 prefix},

     *     as an iterable

     * 
@throws
 IllegalArgumentException if {
@code
 prefix} is {
@code
 null}

     */

    
public
 
Iterable
< String >
 keysWithPrefix
(
String
 prefix
)
 
{

        
if
 
(
prefix 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“calls keysWithPrefix() with null argument”
);

        
}

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        
Node
< Value >
 x 
=
 get
(
root
,
 prefix
,
 
0
);

        
if
 
(

==
 
null
)
 
return
 queue
;

        
if
 
(
x
.
val 
!=
 
null
)
 queue
.
enqueue
(
prefix
);

        collect
(
x
.
mid
,
 
new
 
StringBuilder
(
prefix
),
 queue
);

        
return
 queue
;

    
}

    
// all keys in subtrie rooted at x with given prefix

    
private
 
void
 collect
(
Node
< Value >
 x
,
 
StringBuilder
 prefix
,
 
Queue
< String >
 queue
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        collect
(
x
.
left
,
  prefix
,
 queue
);

        
if
 
(
x
.
val 
!=
 
null
)
 queue
.
enqueue
(
prefix
.
toString
()
 
+
 x
.
c
);

        collect
(
x
.
mid
,
   prefix
.
append
(
x
.
c
),
 queue
);

        prefix
.
deleteCharAt
(
prefix
.
length
()
 

 
1
);

        collect
(
x
.
right
,
 prefix
,
 queue
);

    
}

    
/**

     * Returns all of the keys in the symbol table that match {
@code
 pattern},

     * where . symbol is treated as a wildcard character.

     * 
@param
 pattern the pattern

     * 
@return
 all of the keys in the symbol table that match {
@code
 pattern},

     *     as an iterable, where . is treated as a wildcard character.

     */

    
public
 
Iterable
< String >
 keysThatMatch
(
String
 pattern
)
 
{

        
Queue
< String >
 queue 
=
 
new
 
Queue
< String >
();

        collect
(
root
,
 
new
 
StringBuilder
(),
 
0
,
 pattern
,
 queue
);

        
return
 queue
;

    
}

 

    
private
 
void
 collect
(
Node
< Value >
 x
,
 
StringBuilder
 prefix
,
 
int
 i
,
 
String
 pattern
,
 
Queue
< String >
 queue
)
 
{

        
if
 
(

==
 
null
)
 
return
;

        
char
 c 
=
 pattern
.
charAt
(
i
);

        
if
 
(

==
 
‘.’
 
||
 c 
<  x . c )  collect ( x . left ,  prefix ,  i ,  pattern ,  queue );          if   ( c  ==   '.'   ||  c  ==  x . c )   {              if   ( i  ==  pattern . length ()   -   1   &&  x . val  !=   null )  queue . enqueue ( prefix . toString ()   +  x . c );              if   ( i  <  pattern . length ()   -   1 )   {                 collect ( x . mid ,  prefix . append ( x . c ),  i + 1 ,  pattern ,  queue );                 prefix . deleteCharAt ( prefix . length ()   -   1 );              }          }          if   ( c  ==   '.'   ||  c  >
 x
.
c
)
 collect
(
x
.
right
,
 prefix
,
 i
,
 pattern
,
 queue
);

    
}

    
/**

     * Unit tests the {
@code
 TST} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// build symbol table from standard input

        TST
< Integer >
 st 
=
 
new
 TST
< Integer >
();

        
for
 
(
int
 i 
=
 
0
;
 
!
StdIn
.
isEmpty
();
 i
++
)
 
{

            
String
 key 
=
 
StdIn
.
readString
();

            st
.
put
(
key
,
 i
);

        
}

        
// print results

        
if
 
(
st
.
size
()
 
<   100 )   {              StdOut . println ( "keys(\"\"):" );              for   ( String  key  :  st . keys ())   {                  StdOut . println ( key  +   " "   +  st . get ( key ));              }              StdOut . println ();          }          StdOut . println ( "longestPrefixOf(\"shellsort\"):" );          StdOut . println ( st . longestPrefixOf ( "shellsort" ));          StdOut . println ();          StdOut . println ( "longestPrefixOf(\"shell\"):" );          StdOut . println ( st . longestPrefixOf ( "shell" ));          StdOut . println ();          StdOut . println ( "keysWithPrefix(\"shor\"):" );          for   ( String  s  :  st . keysWithPrefix ( "shor" ))              StdOut . println ( s );          StdOut . println ();          StdOut . println ( "keysThatMatch(\".he.l.\"):" );          for   ( String  s  :  st . keysThatMatch ( ".he.l." ))              StdOut . println ( s );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/TwoPersonZeroSumGame.java edu/princeton/cs/algs4/TwoPersonZeroSumGame.java /******************************************************************************  *  Compilation:  javac TwoPersonZeroSumGame.java  *  Execution:    java TwoPersonZeroSumGame m n  *  Dependencies: LinearProgramming.java StdOut.java  *  *  Solve an m-by-n two-person zero-sum game by reducing it to  *  linear programming. Assuming A is a strictly positive payoff  *  matrix, the optimal row and column player strategies are x* an y*,  *  scaled to be probability distributions.  *  *  (P)  max  y^T 1         (D)  min   1^T x  *       s.t  A^T y <= 1         s.t   A x >= 1

 *                y >= 0                 x >= 0

 *

 *  Row player is x, column player is y.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 TwoPersonZeroSumGame} class represents a data type for

 *  computing optimal row and column strategies to two-person zero-sum games.

 *  

 *  This implementation solves an m-by-n two-person

 *  zero-sum game by reducing it to a linear programming problem.

 *  Assuming the payoff matrix A is strictly positive, the

 *  optimal row and column player strategies x* and y* are obtained

 *  by solving the following primal and dual pair of linear programs,

 *  scaling the results to be probability distributions.

 *  


 *  (P)  max  y^T 1           (D)  min   1^T x

 *       s.t  A^T y ≤ 1         s.t   A x ≥ 1

 *                y ≤ 0                 x ≥ 0

 *  

 *  

 *  If the payoff matrix A has any negative entries, we add

 *  the same constant to every entry so that every entry is positive.

 *  This increases the value of the game by that constant, but does not

 *  change solutions to the two-person zero-sum game.

 *  

 *  This implementation is not suitable for large inputs, as it calls

 *  a bare-bones linear programming solver that is neither fast nor

 *  robust with respect to floating-point roundoff error.

 *  

 *  For additional documentation, see

 *  Section 6.5

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
TwoPersonZeroSumGame
 
{

    
private
 
static
 
final
 
double
 EPSILON 
=
 
1E-8
;

    
private
 
final
 
int
 m
;
            
// number of rows

    
private
 
final
 
int
 n
;
            
// number of columns

    
private
 
LinearProgramming
 lp
;
   
// linear program solver

    
private
 
double
 constant
;
        
// constant added to each entry in payoff matrix

                                    
// (0 if all entries are strictly positive)

 

    
/**

     * Determines an optimal solution to the two-sum zero-sum game

     * with the specified payoff matrix.

     *

     * 
@param
  payoff the m-by-n payoff matrix

     */
 

    
public
 
TwoPersonZeroSumGame
(
double
[][]
 payoff
)
 
{

        m 
=
 payoff
.
length
;

        n 
=
 payoff
[
0
].
length
;

        
double
[]
 c 
=
 
new
 
double
[
n
];

        
double
[]
 b 
=
 
new
 
double
[
m
];

        
double
[][]
 A 
=
 
new
 
double
[
m
][
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )             b [ i ]   =   1.0 ;          for   ( int  j  =   0 ;  j  <  n ;  j ++ )             c [ j ]   =   1.0 ;          // find smallest entry         constant  =   Double . POSITIVE_INFINITY ;          for   ( int  i  =   0 ;  i  <  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                  if   ( payoff [ i ][ j ]   <  constant )                     constant  =  payoff [ i ][ j ];          // add constant  to every entry to make strictly positive          if   ( constant  <=   0 )  constant  =   - constant  +   1 ;          else                constant  =   0 ;          for   ( int  i  =   0 ;  i  <  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 A [ i ][ j ]   =  payoff [ i ][ j ]   +  constant ;         lp  =   new   LinearProgramming ( A ,  b ,  c );          assert  certifySolution ( payoff );      }      /**      * Returns the optimal value of this two-person zero-sum game.      *      *  @return  the optimal value of this two-person zero-sum game      *      */      public   double  value ()   {          return   1.0   /  scale ()   -  constant ;      }      // sum of x[j]      private   double  scale ()   {          double []  x  =  lp . primal ();          double  sum  =   0.0 ;          for   ( int  j  =   0 ;  j  <  n ;  j ++ )             sum  +=  x [ j ];          return  sum ;      }      /**      * Returns the optimal row strategy of this two-person zero-sum game.      *      *  @return  the optimal row strategy x of this two-person zero-sum game

     */

    
public
 
double
[]
 row
()
 
{

        
double
 scale 
=
 scale
();

        
double
[]
 x 
=
 lp
.
primal
();

        
for
 
(
int
 j 
=
 
0
;
 j 
<  n ;  j ++ )             x [ j ]   /=  scale ;          return  x ;      }      /**      * Returns the optimal column strategy of this two-person zero-sum game.      *      *  @return  the optimal column strategy y of this two-person zero-sum game

     */

    
public
 
double
[]
 column
()
 
{

        
double
 scale 
=
 scale
();

        
double
[]
 y 
=
 lp
.
dual
();

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )             y [ i ]   /=  scale ;          return  y ;      }      /**************************************************************************      *      *  The code below is solely for testing correctness of the data type.      *      **************************************************************************/      // is the row vector x primal feasible?      private   boolean  isPrimalFeasible ()   {          double []  x  =  row ();          double  sum  =   0.0 ;          for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {              if   ( x [ j ]   <   0 )   {                  StdOut . println ( "row vector not a probability distribution" );                  StdOut . printf ( "    x[%d] = %f\n" ,  j ,  x [ j ]);                  return   false ;              }             sum  +=  x [ j ];          }          if   ( Math . abs ( sum  -   1.0 )   >
 EPSILON
)
 
{

            
StdOut
.
println
(
“row vector x[] is not a probability distribution”
);

            
StdOut
.
println
(
”    sum = ”
 
+
 sum
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
// is the column vector y dual feasible?

    
private
 
boolean
 isDualFeasible
()
 
{

        
double
[]
 y 
=
 column
();

        
double
 sum 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              if   ( y [ i ]   <   0 )   {                  StdOut . println ( "column vector y[] is not a probability distribution" );                  StdOut . printf ( "    y[%d] = %f\n" ,  i ,  y [ i ]);                  return   false ;              }             sum  +=  y [ i ];          }          if   ( Math . abs ( sum  -   1.0 )   >
 EPSILON
)
 
{

            
StdOut
.
println
(
“column vector not a probability distribution”
);

            
StdOut
.
println
(
”    sum = ”
 
+
 sum
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
// is the solution a Nash equilibrium?

    
private
 
boolean
 isNashEquilibrium
(
double
[][]
 payoff
)
 
{

        
double
[]
 x 
=
 row
();

        
double
[]
 y 
=
 column
();

        
double
 value 
=
 value
();

        
// given row player’s mixed strategy, find column player’s best pure strategy

        
double
 opt1 
=
 
Double
.
NEGATIVE_INFINITY
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )   {              double  sum  =   0.0 ;              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 sum  +=  payoff [ i ][ j ]   *  x [ j ];              }              if   ( sum  >
 opt1
)
 opt1 
=
 sum
;

        
}

        
if
 
(
Math
.
abs
(
opt1 

 value
)
 
>
 EPSILON
)
 
{

            
StdOut
.
println
(
“Optimal value = ”
 
+
 value
);

            
StdOut
.
println
(
“Optimal best response for column player = ”
 
+
 opt1
);

            
return
 
false
;

        
}

        
// given column player’s mixed strategy, find row player’s best pure strategy

        
double
 opt2 
=
 
Double
.
POSITIVE_INFINITY
;

        
for
 
(
int
 j 
=
 
0
;
 j 
<  n ;  j ++ )   {              double  sum  =   0.0 ;              for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {                 sum  +=  payoff [ i ][ j ]   *  y [ i ];              }              if   ( sum  <  opt2 )  opt2  =  sum ;          }          if   ( Math . abs ( opt2  -  value )   >
 EPSILON
)
 
{

            
StdOut
.
println
(
“Optimal value = ”
 
+
 value
);

            
StdOut
.
println
(
“Optimal best response for row player = ”
 
+
 opt2
);

            
return
 
false
;

        
}

        
return
 
true
;

    
}

    
private
 
boolean
 certifySolution
(
double
[][]
 payoff
)
 
{

        
return
 isPrimalFeasible
()
 
&&
 isDualFeasible
()
 
&&
 isNashEquilibrium
(
payoff
);

    
}

    
private
 
static
 
void
 test
(
String
 description
,
 
double
[][]
 payoff
)
 
{

        
StdOut
.
println
();

        
StdOut
.
println
(
description
);

        
StdOut
.
println
(
“————————————”
);

        
int
 m 
=
 payoff
.
length
;

        
int
 n 
=
 payoff
[
0
].
length
;

        
TwoPersonZeroSumGame
 zerosum 
=
 
new
 
TwoPersonZeroSumGame
(
payoff
);

        
double
[]
 x 
=
 zerosum
.
row
();

        
double
[]
 y 
=
 zerosum
.
column
();

        
StdOut
.
print
(
“x[] = [”
);

        
for
 
(
int
 j 
=
 
0
;
 j 
<  n - 1 ;  j ++ )              StdOut . printf ( "%8.4f, " ,  x [ j ]);          StdOut . printf ( "%8.4f]\n" ,  x [ n - 1 ]);          StdOut . print ( "y[] = [" );          for   ( int  i  =   0 ;  i  <  m - 1 ;  i ++ )              StdOut . printf ( "%8.4f, " ,  y [ i ]);          StdOut . printf ( "%8.4f]\n" ,  y [ m - 1 ]);          StdOut . println ( "value =  "   +  zerosum . value ());               }      // row = { 4/7, 3/7 }, column = { 0, 4/7, 3/7 }, value = 20/7      // http://en.wikipedia.org/wiki/Zero-sum      private   static   void  test1 ()   {          double [][]  payoff  =   {              {   30 ,   - 10 ,    20   },              {   10 ,    20 ,   - 20   }          };         test ( "wikipedia" ,  payoff );      }      // skew-symmetric => value = 0

    
// Linear Programming by Chvatal, p. 230

    
private
 
static
 
void
 test2
()
 
{

        
double
[][]
 payoff 
=
 
{

            
{
  
0
,
  
2
,
 

3
,
  
0
 
},

            
{
 

2
,
  
0
,
  
0
,
  
3
 
},

            
{
  
3
,
  
0
,
  
0
,
 

4
 
},

            
{
  
0
,
 

3
,
  
4
,
  
0
 
}

        
};

        test
(
“Chvatal, p. 230”
,
 payoff
);

    
}

    
// Linear Programming by Chvatal, p. 234

    
// row    = { 0, 56/99, 40/99, 0, 0, 2/99, 0, 1/99 }

    
// column = { 28/99, 30/99, 21/99, 20/99 }

    
// value  = 4/99

    
private
 
static
 
void
 test3
()
 
{

        
double
[][]
 payoff 
=
 
{

            
{
  
0
,
  
2
,
 

3
,
  
0
 
},

            
{
 

2
,
  
0
,
  
0
,
  
3
 
},

            
{
  
3
,
  
0
,
  
0
,
 

4
 
},

            
{
  
0
,
 

3
,
  
4
,
  
0
 
},

            
{
  
0
,
  
0
,
 

3
,
  
3
 
},

            
{
 

2
,
  
2
,
  
0
,
  
0
 
},

            
{
  
3
,
 

3
,
  
0
,
  
0
 
},

            
{
  
0
,
  
0
,
  
4
,
 

4
 
}

        
};

        test
(
“Chvatal, p. 234”
,
 payoff
);

    
}

    
// Linear Programming by Chvatal, p. 236

    
// row    = { 0, 2/5, 7/15, 0, 2/15, 0, 0, 0 }

    
// column = { 2/3, 0, 0, 1/3 }

    
// value  = -1/3

    
private
 
static
 
void
 test4
()
 
{

        
double
[][]
 payoff 
=
 
{

            
{
  
0
,
  
2
,
 

1
,
 

1
 
},

            
{
  
0
,
  
1
,
 

2
,
 

1
 
},

            
{
 

1
,
 

1
,
  
1
,
  
1
 
},

            
{
 

1
,
  
0
,
  
0
,
  
1
 
},

            
{
  
1
,
 

2
,
  
0
,
 

3
 
},

            
{
  
1
,
 

1
,
 

1
,
 

3
 
},

            
{
  
0
,
 

3
,
  
2
,
 

1
 
},

            
{
  
0
,
 

2
,
  
1
,
 

1
 
},

        
};

        test
(
“Chvatal p. 236”
,
 payoff
);

    
}

    
// rock, paper, scissors

    
// row    = { 1/3, 1/3, 1/3 }

    
// column = { 1/3, 1/3, 1/3 }

    
private
 
static
 
void
 test5
()
 
{

        
double
[][]
 payoff 
=
 
{

            
{
  
0
,
 

1
,
  
1
 
},

            
{
  
1
,
  
0
,
 

1
 
},

            
{
 

1
,
  
1
,
  
0
 
}

        
};

        test
(
“rock, paper, scisssors”
,
 payoff
);

    
}

    
/**

     * Unit tests the {
@code
 ZeroSumGameToLP} data type.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        test1
();

        test2
();

        test3
();

        test4
();

        test5
();

        
int
 m 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
1
]);

        
double
[][]
 payoff 
=
 
new
 
double
[
m
][
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  m ;  i ++ )              for   ( int  j  =   0 ;  j  <  n ;  j ++ )                 payoff [ i ][ j ]   =   StdRandom . uniform ( - 0.5 ,   0.5 );         test ( "random "   +  m  +   "-by-"   +  n ,  payoff );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/UF.java edu/princeton/cs/algs4/UF.java /******************************************************************************  *  Compilation:  javac UF.java  *  Execution:    java UF < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt  *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt  *                https://algs4.cs.princeton.edu/15uf/largeUF.txt  *  *  Weighted quick-union by rank with path compression by halving.  *  *  % java UF < tinyUF.txt  *  4 3  *  3 8  *  6 5  *  9 4  *  2 1  *  5 0  *  7 2  *  6 1  *  2 components  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  UF} class represents a union–find data type

 *  (also known as the disjoint-sets data type).

 *  It supports the classic union and find operations,

 *  along with a count operation that returns the total number

 *  of sets.

 *  

 *  The union-find data type models a collection of sets containing

 *  n elements, with each element in exactly one set.

 *  The elements are named 0 through n–1.

 *  Initially, there are n sets, with each element in its

 *  own set. The cannonical elemement of a set

 *  (also known as the rootidentifier,

 *  leader, or set representative)

 *  is one distinguished element in the set. Here is a summary of

 *  the operations:

 *  

     *  

  • find(p) returns the canonical element

     *      of the set containing p. The find operation

     *      returns the same value for two elements if and only if

     *      they are in the same set.

     *  

  • union(pq) merges the set

     *      containing element p with the set containing

     *      element q. That is, if p and q

     *      are in different sets, replace these two sets

     *      with a new set that is the union of the two.

     *  

  • count() returns the number of sets.

     *  

 *  

 *  The canonical element of a set can change only when the set

 *  itself changes during a call to union—it cannot

 *  change during a call to either find or count.

 *  

 *  This implementation uses weighted quick union by rank

 *  with path compression by halving.

 *  The constructor takes Θ(n) time, where

 *  n is the number of elements.

 *  The union and find operations take

 *  Θ(log n) time in the worst case.

 *  The count operation takes Θ(1) time.

 *  Moreover, starting from an empty data structure with n sites,

 *  any intermixed sequence of m union and find

 *  operations takes O(m α(n)) time,

 *  where α(n) is the inverse of

 *  Ackermann’s function.

 *  

 *  For alternative implementations of the same API, see

 *  {
@link
 QuickUnionUF}, {
@link
 QuickFindUF}, and {
@link
 WeightedQuickUnionUF}.

 *  For additional documentation, see

 *  Section 1.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 UF 
{

    
private
 
int
[]
 parent
;
  
// parent[i] = parent of i

    
private
 
byte
[]
 rank
;
   
// rank[i] = rank of subtree rooted at i (never more than 31)

    
private
 
int
 count
;
     
// number of components

    
/**

     * Initializes an empty union-find data structure with

     * {
@code
 n} elements {
@code
 0} through {
@code
 n-1}.

     * Initially, each elements is in its own set.

     *

     * 
@param
  n the number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n < 0}      */      public  UF ( int  n )   {          if   ( n  <   0 )   throw   new   IllegalArgumentException ();         count  =  n ;         parent  =   new   int [ n ];         rank  =   new   byte [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             parent [ i ]   =  i ;             rank [ i ]   =   0 ;          }      }      /**      * Returns the canonical element of the set containing element { @code  p}.      *      *  @param   p an element      *  @return  the canonical element of the set containing { @code  p}      *  @throws  IllegalArgumentException unless { @code  0 <= p < n}      */      public   int  find ( int  p )   {         validate ( p );          while   ( p  !=  parent [ p ])   {             parent [ p ]   =  parent [ parent [ p ]];      // path compression by halving             p  =  parent [ p ];          }          return  p ;      }      /**      * Returns the number of sets.      *      *  @return  the number of sets (between { @code  1} and { @code  n})      */      public   int  count ()   {          return  count ;      }         /**      * Returns true if the two elements are in the same set.      *      *  @param   p one element      *  @param   q the other element      *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless      *         both { @code  0 <= p < n} and { @code  0 <= q < n}      *  @deprecated  Replace with two calls to { @link  #find(int)}.      */     @ Deprecated      public   boolean  connected ( int  p ,   int  q )   {          return  find ( p )   ==  find ( q );      }         /**      * Merges the set containing element { @code  p} with the       * the set containing element { @code  q}.      *      *  @param   p one element      *  @param   q the other element      *  @throws  IllegalArgumentException unless      *         both { @code  0 <= p < n} and { @code  0 <= q < n}      */      public   void  union ( int  p ,   int  q )   {          int  rootP  =  find ( p );          int  rootQ  =  find ( q );          if   ( rootP  ==  rootQ )   return ;          // make root of smaller rank point to root of larger rank          if        ( rank [ rootP ]   <  rank [ rootQ ])  parent [ rootP ]   =  rootQ ;          else   if   ( rank [ rootP ]   >
 rank
[
rootQ
])
 parent
[
rootQ
]
 
=
 rootP
;

        
else
 
{

            parent
[
rootQ
]
 
=
 rootP
;

            rank
[
rootP
]
++
;

        
}

        count

;

    
}

    
// validate that p is a valid index

    
private
 
void
 validate
(
int
 p
)
 
{

        
int
 n 
=
 parent
.
length
;

        
if
 
(

<   0   ||  p  >=
 n
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index ”
 
+
 p 
+
 
” is not between 0 and ”
 
+
 
(
n

1
));
  

        
}

    
}

    
/**

     * Reads in a an integer {
@code
 n} and a sequence of pairs of integers

     * (between {
@code
 0} and {
@code
 n-1}) from standard input, where each integer

     * in the pair represents some element;

     * if the elements are in different sets, merge the two sets

     * and print the pair to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        UF uf 
=
 
new
 UF
(
n
);

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
int
 p 
=
 
StdIn
.
readInt
();

            
int
 q 
=
 
StdIn
.
readInt
();

            
if
 
(
uf
.
find
(
p
)
 
==
 uf
.
find
(
q
))
 
continue
;

            uf
.
union
(
p
,
 q
);

            
StdOut
.
println
(

+
 
” ”
 
+
 q
);

        
}

        
StdOut
.
println
(
uf
.
count
()
 
+
 
” components”
);

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Vector.java
edu/princeton/cs/algs4/Vector.java
/******************************************************************************

 *  Compilation:  javac Vector.java

 *  Execution:    java Vector

 *  Dependencies: StdOut.java

 *

 *  Implementation of a vector of real numbers.

 *

 *  This class is implemented to be immutable: once the client program

 *  initialize a Vector, it cannot change any of its fields

 *  (d or data[i]) either directly or indirectly. Immutability is a

 *  very desirable feature of a data type.

 *

 *  % java Vector

 *     x     = [ 1.0 2.0 3.0 4.0 ]

 *     y     = [ 5.0 2.0 4.0 1.0 ]

 *     z     = [ 6.0 4.0 7.0 5.0 ]

 *   10z     = [ 60.0 40.0 70.0 50.0 ]

 *    |x|    = 5.477225575051661

 *     = 25.0

 * 

 *

 *  Note that Vector is also the name of an unrelated Java library class

 *  in the package java.util.

 *

 ******************************************************************************/

package
 edu
.
princeton
.
cs
.
algs4
;

/**

 *  The {
@code
 Vector} class represents a d-dimensional Euclidean vector.

 *  Vectors are immutable: their values cannot be changed after they are created.

 *  It includes methods for addition, subtraction,

 *  dot product, scalar product, unit vector, Euclidean norm, and the Euclidean

 *  distance between two vectors.

 *  

 *  For additional documentation, 

 *  see Section 1.2 of 

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne. 

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Vector
 
{
 

    
private
 
int
 d
;
               
// dimension of the vector

    
private
 
double
[]
 data
;
       
// array of vector’s components

    
/**

     * Initializes a d-dimensional zero vector.

     *

     * 
@param
 d the dimension of the vector

     */

    
public
 
Vector
(
int
 d
)
 
{

        
this
.

=
 d
;

        data 
=
 
new
 
double
[
d
];

    
}

    
/**

     * Initializes a vector from either an array or a vararg list.

     * The vararg syntax supports a constructor that takes a variable number of

     * arugments such as Vector x = new Vector(1.0, 2.0, 3.0, 4.0).

     *

     * 
@param
 a  the array or vararg list

     */

    
public
 
Vector
(
double

 a
)
 
{

        d 
=
 a
.
length
;

        
// defensive copy so that client can’t alter our copy of data[]

        data 
=
 
new
 
double
[
d
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  d ;  i ++ )             data [ i ]   =  a [ i ];      }      /**      * Returns the length of this vector.      *      *  @return  the dimension of this vector      *  @deprecated  Replaced by { @link  #dimension()}.      */     @ Deprecated      public   int  length ()   {          return  d ;      }      /**      * Returns the dimension of this vector.      *      *  @return  the dimension of this vector      */      public   int  dimension ()   {          return  d ;      }      /**      * Returns the dot product of this vector with the specified vector.      *      *  @param   that the other vector      *  @return  the dot product of this vector and that vector      *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal      */      public   double  dot ( Vector  that )   {          if   ( this . d  !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             sum  =  sum  +   ( this . data [ i ]   *  that . data [ i ]);          return  sum ;      }      /**      * Returns the magnitude of this vector.      * This is also known as the L2 norm or the Euclidean norm.      *      *  @return  the magnitude of this vector      */      public   double  magnitude ()   {          return   Math . sqrt ( this . dot ( this ));      }      /**      * Returns the Euclidean distance between this vector and the specified vector.      *      *  @param   that the other vector       *  @return  the Euclidean distance between this vector and that vector      *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal      */      public   double  distanceTo ( Vector  that )   {          if   ( this . d  !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );          return   this . minus ( that ). magnitude ();      }      /**      * Returns the sum of this vector and the specified vector.      *      *  @param   that the vector to add to this vector      *  @return  the vector whose value is { @code  (this + that)}      *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal      */      public   Vector  plus ( Vector  that )   {          if   ( this . d  !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );          Vector  c  =   new   Vector ( d );          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             c . data [ i ]   =   this . data [ i ]   +  that . data [ i ];          return  c ;      }      /**      * Returns the difference between this vector and the specified vector.      *      *  @param   that the vector to subtract from this vector      *  @return  the vector whose value is { @code  (this - that)}      *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal      */      public   Vector  minus ( Vector  that )   {          if   ( this . d  !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );          Vector  c  =   new   Vector ( d );          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             c . data [ i ]   =   this . data [ i ]   -  that . data [ i ];          return  c ;      }      /**      * Returns the ith cartesian coordinate.      *      *  @param   i the coordinate index      *  @return  the ith cartesian coordinate      */      public   double  cartesian ( int  i )   {          return  data [ i ];      }      /**      * Returns the scalar-vector product of this vector and the specified scalar      *      *  @param   alpha the scalar      *  @return  the vector whose value is { @code  (alpha * this)}      *  @deprecated  Replaced by { @link  #scale(double)}.      */     @ Deprecated      public   Vector  times ( double  alpha )   {          Vector  c  =   new   Vector ( d );          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             c . data [ i ]   =  alpha  *  data [ i ];          return  c ;      }      /**      * Returns the scalar-vector product of this vector and the specified scalar      *      *  @param   alpha the scalar      *  @return  the vector whose value is { @code  (alpha * this)}      */      public   Vector  scale ( double  alpha )   {          Vector  c  =   new   Vector ( d );          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             c . data [ i ]   =  alpha  *  data [ i ];          return  c ;      }      /**      * Returns a unit vector in the direction of this vector.      *      *  @return  a unit vector in the direction of this vector      *  @throws  ArithmeticException if this vector is the zero vector      */      public   Vector  direction ()   {          if   ( this . magnitude ()   ==   0.0 )   throw   new   ArithmeticException ( "Zero-vector has no direction" );          return   this . times ( 1.0   /   this . magnitude ());      }      /**      * Returns a string representation of this vector.      *      *  @return  a string representation of this vector, which consists of the       *         the vector entries, separates by single spaces      */      public   String  toString ()   {          StringBuilder  s  =   new   StringBuilder ();          for   ( int  i  =   0 ;  i  <  d ;  i ++ )             s . append ( data [ i ]   +   " " );          return  s . toString ();      }      /**      * Unit tests the { @code  Vector} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          double []  xdata  =   {   1.0 ,   2.0 ,   3.0 ,   4.0   };          double []  ydata  =   {   5.0 ,   2.0 ,   4.0 ,   1.0   };          Vector  x  =   new   Vector ( xdata );          Vector  y  =   new   Vector ( ydata );          StdOut . println ( "   x       = "   +  x );          StdOut . println ( "   y       = "   +  y );          Vector  z  =  x . plus ( y );          StdOut . println ( "   z       = "   +  z );         z  =  z . times ( 10.0 );          StdOut . println ( " 10z       = "   +  z );          StdOut . println ( "  |x|      = "   +  x . magnitude ());          StdOut . println ( "     = ”
 
+
 x
.
dot
(
y
));

        
StdOut
.
println
(
“dist(x, y) = ”
 
+
 x
.
distanceTo
(
y
));

        
StdOut
.
println
(
“dir(x)     = ”
 
+
 x
.
direction
());

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/WeightedQuickUnionUF.java
edu/princeton/cs/algs4/WeightedQuickUnionUF.java
/******************************************************************************

 *  Compilation:  javac WeightedQuickUnionUF.java

 *  Execution:  java WeightedQuickUnionUF < input.txt  *  Dependencies: StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt  *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt  *                https://algs4.cs.princeton.edu/15uf/largeUF.txt  *  *  Weighted quick-union (without path compression).  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  WeightedQuickUnionUF} class represents a union–find data type

 *  (also known as the disjoint-sets data type).

 *  It supports the classic union and find operations,

 *  along with a count operation that returns the total number

 *  of sets.

 *  

 *  The union-find data type models a collection of sets containing

 *  n elements, with each element in exactly one set.

 *  The elements are named 0 through n–1.

 *  Initially, there are n sets, with each element in its

 *  own set. The cannonical elemement of a set

 *  (also known as the rootidentifier,

 *  leader, or set representative)

 *  is one distinguished element in the set. Here is a summary of

 *  the operations:

 *  

     *  

  • find(p) returns the canonical element

     *      of the set containing p. The find operation

     *      returns the same value for two elements if and only if

     *      they are in the same set.

     *  

  • union(pq) merges the set

     *      containing element p with the set containing

     *      element q. That is, if p and q

     *      are in different sets, replace these two sets

     *      with a new set that is the union of the two.

     *  

  • count() returns the number of sets.

     *  

 *  

 *  The canonical element of a set can change only when the set

 *  itself changes during a call to union—it cannot

 *  change during a call to either find or count.

 *  

 *  This implementation uses weighted quick union by size

 *  (without path compression).

 *  The constructor takes Θ(n), where n

 *  is the number of elements.

 *  The union and find

 *  operations  take Θ(log n) time in the worst

 *  case. The count operation takes Θ(1) time.

 *  

 *  For alternative implementations of the same API, see

 *  {
@link
 UF}, {
@link
 QuickFindUF}, and {
@link
 QuickUnionUF}.

 *  For additional documentation, see

 *  Section 1.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
WeightedQuickUnionUF
 
{

    
private
 
int
[]
 parent
;
   
// parent[i] = parent of i

    
private
 
int
[]
 size
;
     
// size[i] = number of elements in subtree rooted at i

    
private
 
int
 count
;
      
// number of components

    
/**

     * Initializes an empty union-find data structure with

     * {
@code
 n} elements {
@code
 0} through {
@code
 n-1}. 

     * Initially, each elements is in its own set.

     *

     * 
@param
  n the number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n < 0}      */      public   WeightedQuickUnionUF ( int  n )   {         count  =  n ;         parent  =   new   int [ n ];         size  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             parent [ i ]   =  i ;             size [ i ]   =   1 ;          }      }      /**      * Returns the number of sets.      *      *  @return  the number of sets (between { @code  1} and { @code  n})      */      public   int  count ()   {          return  count ;      }         /**      * Returns the canonical element of the set containing element { @code  p}.      *      *  @param   p an element      *  @return  the canonical element of the set containing { @code  p}      *  @throws  IllegalArgumentException unless { @code  0 <= p < n}      */      public   int  find ( int  p )   {         validate ( p );          while   ( p  !=  parent [ p ])             p  =  parent [ p ];          return  p ;      }      /**      * Returns true if the two elements are in the same set.      *       *  @param   p one element      *  @param   q the other element      *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;      *         { @code  false} otherwise      *  @throws  IllegalArgumentException unless      *         both { @code  0 <= p < n} and { @code  0 <= q < n}      *  @deprecated  Replace with two calls to { @link  #find(int)}.      */     @ Deprecated      public   boolean  connected ( int  p ,   int  q )   {          return  find ( p )   ==  find ( q );      }      // validate that p is a valid index      private   void  validate ( int  p )   {          int  n  =  parent . length ;          if   ( p  <   0   ||  p  >=
 n
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“index ”
 
+
 p 
+
 
” is not between 0 and ”
 
+
 
(
n

1
));
  

        
}

    
}

    
/**

     * Merges the set containing element {
@code
 p} with the 

     * the set containing element {
@code
 q}.

     *

     * 
@param
  p one element

     * 
@param
  q the other element

     * 
@throws
 IllegalArgumentException unless

     *         both {
@code
 0 <= p < n} and { @code  0 <= q < n}      */      public   void  union ( int  p ,   int  q )   {          int  rootP  =  find ( p );          int  rootQ  =  find ( q );          if   ( rootP  ==  rootQ )   return ;          // make smaller root point to larger one          if   ( size [ rootP ]   <  size [ rootQ ])   {             parent [ rootP ]   =  rootQ ;             size [ rootQ ]   +=  size [ rootP ];          }          else   {             parent [ rootQ ]   =  rootP ;             size [ rootP ]   +=  size [ rootQ ];          }         count -- ;      }      /**      * Reads in a an integer { @code  n} and a sequence of pairs of integers      * (between { @code  0} and { @code  n-1}) from standard input, where each integer      * in the pair represents some element;      * if the elements are in different sets, merge the two sets      * and print the pair to standard output.      *       *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  n  =   StdIn . readInt ();          WeightedQuickUnionUF  uf  =   new   WeightedQuickUnionUF ( n );          while   ( ! StdIn . isEmpty ())   {              int  p  =   StdIn . readInt ();              int  q  =   StdIn . readInt ();              if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;             uf . union ( p ,  q );              StdOut . println ( p  +   " "   +  q );          }          StdOut . println ( uf . count ()   +   " components" );      } } /******************************************************************************  *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.  *  *  This file is part of algs4.jar, which accompanies the textbook  *  *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,  *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.  *      http://algs4.cs.princeton.edu  *  *  *  algs4.jar is free software: you can redistribute it and/or modify  *  it under the terms of the GNU General Public License as published by  *  the Free Software Foundation, either version 3 of the License, or  *  (at your option) any later version.  *  *  algs4.jar is distributed in the hope that it will be useful,  *  but WITHOUT ANY WARRANTY; without even the implied warranty of  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  *  GNU General Public License for more details.  *  *  You should have received a copy of the GNU General Public License  *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.  ******************************************************************************/ edu/princeton/cs/algs4/WhiteFilter.java edu/princeton/cs/algs4/WhiteFilter.java /******************************************************************************  *  Compilation:  javac WhiteFilter.java  *  Execution:    java WhiteFilter whitelist.txt < input.txt  *  Dependencies: SET In.java StdIn.java StdOut.java  *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt  *                https://algs4.cs.princeton.edu/35applications/list.txt  *   *  Read in a whitelist of words from a file. Then read in a list of  *  words from standard input and print out all those words that  *  are in the first file.  *   *  % more tinyTale.txt   *  it was the best of times it was the worst of times   *  it was the age of wisdom it was the age of foolishness   *  it was the epoch of belief it was the epoch of incredulity   *  it was the season of light it was the season of darkness   *  it was the spring of hope it was the winter of despair  *  *  % more list.txt   *  was it the of   *   *  % java WhiteFilter list.txt < tinyTale.txt   *  it was the of it was the of  *  it was the of it was the of  *  it was the of it was the of  *  it was the of it was the of  *  it was the of it was the of  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  WhiteFilter} class provides a client for reading in a whitelist

 *  of words from a file; then, reading in a sequence of words from standard input,

 *  printing out each word that appears in the file.

 *  It is useful as a test client for various symbol table implementations.

 *  

 *  For additional documentation, see Section 3.5 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
WhiteFilter
 
{
  

    
// Do not instantiate.

    
private
 
WhiteFilter
()
 
{
 
}

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        SET
< String >
 set 
=
 
new
 SET
< String >
();

        
// read in strings and add to set

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
while
 
(
!
in
.
isEmpty
())
 
{

            
String
 word 
=
 in
.
readString
();

            set
.
add
(
word
);

        
}

        
// read in string from standard input, printing out all exceptions

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
String
 word 
=
 
StdIn
.
readString
();

            
if
 
(
set
.
contains
(
word
))

                
StdOut
.
println
(
word
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Whitelist.java
edu/princeton/cs/algs4/Whitelist.java
/******************************************************************************

 *  Compilation:  javac Whitelist.java

 *  Execution:    java Whitelist whitelist.txt < data.txt  *  Dependencies: StaticSetOfInts.java In.java StdOut.java  *  *  Data files:   https://algs4.cs.princeton.edu/11model/tinyW.txt  *                https://algs4.cs.princeton.edu/11model/tinyT.txt  *                https://algs4.cs.princeton.edu/11model/largeW.txt  *                https://algs4.cs.princeton.edu/11model/largeT.txt  *  *  Whitelist filter.  *  *  *  % java Whitelist tinyW.txt < tinyT.txt  *  50  *  99  *  13  *  *  % java Whitelist largeW.txt < largeT.txt | more  *  499569  *  984875  *  295754  *  207807  *  140925  *  161828  *  [367,966 total values]  *  ******************************************************************************/ package  edu . princeton . cs . algs4 ; /**  *  The { @code  Whitelist} class provides a client for reading in  *  a set of integers from a file; reading in a sequence of integers  *  from standard input; and printing to standard output those   *  integers not in the whitelist.  *  

 *  For additional documentation, see Section 1.2 of

 *  Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Whitelist
 
{

    
// Do not instantiate.

    
private
 
Whitelist
()
 
{
 
}

    
/**

     * Reads in a sequence of integers from the whitelist file, specified as

     * a command-line argument. Reads in integers from standard input and

     * prints to standard output those integers that are not in the file.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
In
 in 
=
 
new
 
In
(
args
[
0
]);

        
int
[]
 white 
=
 in
.
readAllInts
();

        
StaticSETofInts
 set 
=
 
new
 
StaticSETofInts
(
white
);

        
// Read key, print if not in whitelist.

        
while
 
(
!
StdIn
.
isEmpty
())
 
{

            
int
 key 
=
 
StdIn
.
readInt
();

            
if
 
(
!
set
.
contains
(
key
))

                
StdOut
.
println
(
key
);

        
}

    
}

}

/******************************************************************************

 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.

 *

 *  This file is part of algs4.jar, which accompanies the textbook

 *

 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,

 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.

 *      http://algs4.cs.princeton.edu

 *

 *

 *  algs4.jar is free software: you can redistribute it and/or modify

 *  it under the terms of the GNU General Public License as published by

 *  the Free Software Foundation, either version 3 of the License, or

 *  (at your option) any later version.

 *

 *  algs4.jar is distributed in the hope that it will be useful,

 *  but WITHOUT ANY WARRANTY; without even the implied warranty of

 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

 *  GNU General Public License for more details.

 *

 *  You should have received a copy of the GNU General Public License

 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.

 ******************************************************************************/

edu/princeton/cs/algs4/Accumulator.class
package edu.princeton.cs.algs4;
public synchronized class Accumulator {
private int n;
private double sum;
private double mu;
public void Accumulator();
public void addDataValue(double);
public double mean();
public double var();
public double stddev();
public int count();
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/AcyclicLP.class
package edu.princeton.cs.algs4;
public synchronized class AcyclicLP {
private double[] distTo;
private DirectedEdge[] edgeTo;
public void AcyclicLP(EdgeWeightedDigraph, int);
private void relax(DirectedEdge);
public double distTo(int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/AcyclicSP.class
package edu.princeton.cs.algs4;
public synchronized class AcyclicSP {
private double[] distTo;
private DirectedEdge[] edgeTo;
public void AcyclicSP(EdgeWeightedDigraph, int);
private void relax(DirectedEdge);
public double distTo(int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph$AdjIterator.class
package edu.princeton.cs.algs4;
synchronized class AdjMatrixEdgeWeightedDigraph$AdjIterator implements java.util.Iterator, Iterable {
private int v;
private int w;
public void AdjMatrixEdgeWeightedDigraph$AdjIterator(AdjMatrixEdgeWeightedDigraph, int);
public java.util.Iterator iterator();
public boolean hasNext();
public DirectedEdge next();
public void remove();
}

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.class
package edu.princeton.cs.algs4;
public synchronized class AdjMatrixEdgeWeightedDigraph {
private static final String NEWLINE;
private final int V;
private int E;
private DirectedEdge[][] adj;
public void AdjMatrixEdgeWeightedDigraph(int);
public void AdjMatrixEdgeWeightedDigraph(int, int);
public int V();
public int E();
public void addEdge(DirectedEdge);
public Iterable adj(int);
public String toString();
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Alphabet.class
package edu.princeton.cs.algs4;
public synchronized class Alphabet {
public static final Alphabet BINARY;
public static final Alphabet OCTAL;
public static final Alphabet DECIMAL;
public static final Alphabet HEXADECIMAL;
public static final Alphabet DNA;
public static final Alphabet LOWERCASE;
public static final Alphabet UPPERCASE;
public static final Alphabet PROTEIN;
public static final Alphabet BASE64;
public static final Alphabet ASCII;
public static final Alphabet EXTENDED_ASCII;
public static final Alphabet UNICODE16;
private char[] alphabet;
private int[] inverse;
private final int R;
public void Alphabet(String);
private void Alphabet(int);
public void Alphabet();
public boolean contains(char);
public int R();
public int radix();
public int lgR();
public int toIndex(char);
public int[] toIndices(String);
public char toChar(int);
public String toChars(int[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/AmericanFlag.class
package edu.princeton.cs.algs4;
public synchronized class AmericanFlag {
private static final int BITS_PER_BYTE = 8;
private static final int BITS_PER_INT = 32;
private static final int R = 256;
private static final int CUTOFF = 15;
private void AmericanFlag();
private static int charAt(String, int);
public static void sort(String[]);
public static void sort(String[], int, int);
private static void insertion(String[], int, int, int);
private static void exch(String[], int, int);
private static boolean less(String, String, int);
public static void sort(int[]);
private static void sort(int[], int, int);
private static void insertion(int[], int, int, int);
private static void exch(int[], int, int);
private static boolean less(int, int, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/AmericanFlagX.class
package edu.princeton.cs.algs4;
public synchronized class AmericanFlagX {
private static final int R = 256;
private static final int CUTOFF = 15;
private void AmericanFlagX();
private static int charAt(String, int);
public static void sort(String[]);
public static void sort(String[], int, int);
private static void insertion(String[], int, int, int);
private static void exch(String[], int, int);
private static boolean less(String, String, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Arbitrage.class
package edu.princeton.cs.algs4;
public synchronized class Arbitrage {
private void Arbitrage();
public static void main(String[]);
}

edu/princeton/cs/algs4/AssignmentProblem.class
package edu.princeton.cs.algs4;
public synchronized class AssignmentProblem {
private static final double FLOATING_POINT_EPSILON = 1.0E-14;
private static final int UNMATCHED = -1;
private int n;
private double[][] weight;
private double minWeight;
private double[] px;
private double[] py;
private int[] xy;
private int[] yx;
public void AssignmentProblem(double[][]);
private void augment();
private double reducedCost(int, int);
public double dualRow(int);
public double dualCol(int);
public int sol(int);
public double weight();
private void validate(int);
private boolean isDualFeasible();
private boolean isComplementarySlack();
private boolean isPerfectMatching();
private boolean certifySolution();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Average.class
package edu.princeton.cs.algs4;
public synchronized class Average {
private void Average();
public static void main(String[]);
}

edu/princeton/cs/algs4/AVLTreeST.class
package edu.princeton.cs.algs4;
public synchronized class AVLTreeST {
private AVLTreeST$Node root;
public void AVLTreeST();
public boolean isEmpty();
public int size();
private int size(AVLTreeST$Node);
public int height();
private int height(AVLTreeST$Node);
public Object get(Comparable);
private AVLTreeST$Node get(AVLTreeST$Node, Comparable);
public boolean contains(Comparable);
public void put(Comparable, Object);
private AVLTreeST$Node put(AVLTreeST$Node, Comparable, Object);
private AVLTreeST$Node balance(AVLTreeST$Node);
private int balanceFactor(AVLTreeST$Node);
private AVLTreeST$Node rotateRight(AVLTreeST$Node);
private AVLTreeST$Node rotateLeft(AVLTreeST$Node);
public void delete(Comparable);
private AVLTreeST$Node delete(AVLTreeST$Node, Comparable);
public void deleteMin();
private AVLTreeST$Node deleteMin(AVLTreeST$Node);
public void deleteMax();
private AVLTreeST$Node deleteMax(AVLTreeST$Node);
public Comparable min();
private AVLTreeST$Node min(AVLTreeST$Node);
public Comparable max();
private AVLTreeST$Node max(AVLTreeST$Node);
public Comparable floor(Comparable);
private AVLTreeST$Node floor(AVLTreeST$Node, Comparable);
public Comparable ceiling(Comparable);
private AVLTreeST$Node ceiling(AVLTreeST$Node, Comparable);
public Comparable select(int);
private AVLTreeST$Node select(AVLTreeST$Node, int);
public int rank(Comparable);
private int rank(Comparable, AVLTreeST$Node);
public Iterable keys();
public Iterable keysInOrder();
private void keysInOrder(AVLTreeST$Node, Queue);
public Iterable keysLevelOrder();
public Iterable keys(Comparable, Comparable);
private void keys(AVLTreeST$Node, Queue, Comparable, Comparable);
public int size(Comparable, Comparable);
private boolean check();
private boolean isAVL();
private boolean isAVL(AVLTreeST$Node);
private boolean isBST();
private boolean isBST(AVLTreeST$Node, Comparable, Comparable);
private boolean isSizeConsistent();
private boolean isSizeConsistent(AVLTreeST$Node);
private boolean isRankConsistent();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/AVLTreeST$Node.class
package edu.princeton.cs.algs4;
synchronized class AVLTreeST$Node {
private final Comparable key;
private Object val;
private int height;
private int size;
private AVLTreeST$Node left;
private AVLTreeST$Node right;
public void AVLTreeST$Node(AVLTreeST, Comparable, Object, int, int);
}

edu/princeton/cs/algs4/Bag$1.class
package edu.princeton.cs.algs4;
synchronized class Bag$1 {
}

edu/princeton/cs/algs4/Bag.class
package edu.princeton.cs.algs4;
public synchronized class Bag implements Iterable {
private Bag$Node first;
private int n;
public void Bag();
public boolean isEmpty();
public int size();
public void add(Object);
public java.util.Iterator iterator();
public static void main(String[]);
}

edu/princeton/cs/algs4/Bag$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class Bag$ListIterator implements java.util.Iterator {
private Bag$Node current;
public void Bag$ListIterator(Bag, Bag$Node);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/Bag$Node.class
package edu.princeton.cs.algs4;
synchronized class Bag$Node {
private Object item;
private Bag$Node next;
private void Bag$Node();
}

edu/princeton/cs/algs4/BellmanFordSP.class
package edu.princeton.cs.algs4;
public synchronized class BellmanFordSP {
private double[] distTo;
private DirectedEdge[] edgeTo;
private boolean[] onQueue;
private Queue queue;
private int cost;
private Iterable cycle;
public void BellmanFordSP(EdgeWeightedDigraph, int);
private void relax(EdgeWeightedDigraph, int);
public boolean hasNegativeCycle();
public Iterable negativeCycle();
private void findNegativeCycle();
public double distTo(int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private boolean check(EdgeWeightedDigraph, int);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BinaryDump.class
package edu.princeton.cs.algs4;
public synchronized class BinaryDump {
private void BinaryDump();
public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryIn.class
package edu.princeton.cs.algs4;
public final synchronized class BinaryIn {
private static final int EOF = -1;
private java.io.BufferedInputStream in;
private int buffer;
private int n;
public void BinaryIn();
public void BinaryIn(java.io.InputStream);
public void BinaryIn(java.net.Socket);
public void BinaryIn(java.net.URL);
public void BinaryIn(String);
private void fillBuffer();
public boolean exists();
public boolean isEmpty();
public boolean readBoolean();
public char readChar();
public char readChar(int);
public String readString();
public short readShort();
public int readInt();
public int readInt(int);
public long readLong();
public double readDouble();
public float readFloat();
public byte readByte();
public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryInsertion.class
package edu.princeton.cs.algs4;
public synchronized class BinaryInsertion {
private void BinaryInsertion();
public static void sort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BinaryOut.class
package edu.princeton.cs.algs4;
public final synchronized class BinaryOut {
private java.io.BufferedOutputStream out;
private int buffer;
private int n;
public void BinaryOut();
public void BinaryOut(java.io.OutputStream);
public void BinaryOut(String);
public void BinaryOut(java.net.Socket);
private void writeBit(boolean);
private void writeByte(int);
private void clearBuffer();
public void flush();
public void close();
public void write(boolean);
public void write(byte);
public void write(int);
public void write(int, int);
public void write(double);
public void write(long);
public void write(float);
public void write(short);
public void write(char);
public void write(char, int);
public void write(String);
public void write(String, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BinarySearch.class
package edu.princeton.cs.algs4;
public synchronized class BinarySearch {
private void BinarySearch();
public static int indexOf(int[], int);
public static int rank(int, int[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/BinarySearchST.class
package edu.princeton.cs.algs4;
public synchronized class BinarySearchST {
private static final int INIT_CAPACITY = 2;
private Comparable[] keys;
private Object[] vals;
private int n;
public void BinarySearchST();
public void BinarySearchST(int);
private void resize(int);
public int size();
public boolean isEmpty();
public boolean contains(Comparable);
public Object get(Comparable);
public int rank(Comparable);
public void put(Comparable, Object);
public void delete(Comparable);
public void deleteMin();
public void deleteMax();
public Comparable min();
public Comparable max();
public Comparable select(int);
public Comparable floor(Comparable);
public Comparable ceiling(Comparable);
public int size(Comparable, Comparable);
public Iterable keys();
public Iterable keys(Comparable, Comparable);
private boolean check();
private boolean isSorted();
private boolean rankCheck();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BinaryStdIn.class
package edu.princeton.cs.algs4;
public final synchronized class BinaryStdIn {
private static final int EOF = -1;
private static java.io.BufferedInputStream in;
private static int buffer;
private static int n;
private static boolean isInitialized;
private void BinaryStdIn();
private static void initialize();
private static void fillBuffer();
public static void close();
public static boolean isEmpty();
public static boolean readBoolean();
public static char readChar();
public static char readChar(int);
public static String readString();
public static short readShort();
public static int readInt();
public static int readInt(int);
public static long readLong();
public static double readDouble();
public static float readFloat();
public static byte readByte();
public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryStdOut.class
package edu.princeton.cs.algs4;
public final synchronized class BinaryStdOut {
private static java.io.BufferedOutputStream out;
private static int buffer;
private static int n;
private static boolean isInitialized;
private void BinaryStdOut();
private static void initialize();
private static void writeBit(boolean);
private static void writeByte(int);
private static void clearBuffer();
public static void flush();
public static void close();
public static void write(boolean);
public static void write(byte);
public static void write(int);
public static void write(int, int);
public static void write(double);
public static void write(long);
public static void write(float);
public static void write(short);
public static void write(char);
public static void write(char, int);
public static void write(String);
public static void write(String, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BinomialMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$1 {
}

edu/princeton/cs/algs4/BinomialMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class BinomialMinPQ implements Iterable {
private BinomialMinPQ$Node head;
private final java.util.Comparator comp;
public void BinomialMinPQ();
public void BinomialMinPQ(java.util.Comparator);
public void BinomialMinPQ(Object[]);
public void BinomialMinPQ(java.util.Comparator, Object[]);
public boolean isEmpty();
public int size();
public void insert(Object);
public Object minKey();
public Object delMin();
public BinomialMinPQ union(BinomialMinPQ);
private boolean greater(Object, Object);
private void link(BinomialMinPQ$Node, BinomialMinPQ$Node);
private BinomialMinPQ$Node eraseMin();
private BinomialMinPQ$Node merge(BinomialMinPQ$Node, BinomialMinPQ$Node, BinomialMinPQ$Node);
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/BinomialMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$MyComparator implements java.util.Comparator {
private void BinomialMinPQ$MyComparator(BinomialMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/BinomialMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$MyIterator implements java.util.Iterator {
BinomialMinPQ data;
public void BinomialMinPQ$MyIterator(BinomialMinPQ);
private BinomialMinPQ$Node clone(BinomialMinPQ$Node, BinomialMinPQ$Node);
public boolean hasNext();
public Object next();
public void remove();
}

edu/princeton/cs/algs4/BinomialMinPQ$Node.class
package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$Node {
Object key;
int order;
BinomialMinPQ$Node child;
BinomialMinPQ$Node sibling;
private void BinomialMinPQ$Node(BinomialMinPQ);
}

edu/princeton/cs/algs4/Bipartite.class
package edu.princeton.cs.algs4;
public synchronized class Bipartite {
private boolean isBipartite;
private boolean[] color;
private boolean[] marked;
private int[] edgeTo;
private Stack cycle;
public void Bipartite(Graph);
private void dfs(Graph, int);
public boolean isBipartite();
public boolean color(int);
public Iterable oddCycle();
private boolean check(Graph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BipartiteMatching.class
package edu.princeton.cs.algs4;
public synchronized class BipartiteMatching {
private static final int UNMATCHED = -1;
private final int V;
private BipartiteX bipartition;
private int cardinality;
private int[] mate;
private boolean[] inMinVertexCover;
private boolean[] marked;
private int[] edgeTo;
public void BipartiteMatching(Graph);
private boolean hasAugmentingPath(Graph);
private boolean isResidualGraphEdge(int, int);
public int mate(int);
public boolean isMatched(int);
public int size();
public boolean isPerfect();
public boolean inMinVertexCover(int);
private void validate(int);
private boolean certifySolution(Graph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BipartiteX.class
package edu.princeton.cs.algs4;
public synchronized class BipartiteX {
private static final boolean WHITE = 0;
private static final boolean BLACK = 1;
private boolean isBipartite;
private boolean[] color;
private boolean[] marked;
private int[] edgeTo;
private Queue cycle;
public void BipartiteX(Graph);
private void bfs(Graph, int);
public boolean isBipartite();
public boolean color(int);
public Iterable oddCycle();
private boolean check(Graph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BlackFilter.class
package edu.princeton.cs.algs4;
public synchronized class BlackFilter {
private void BlackFilter();
public static void main(String[]);
}

edu/princeton/cs/algs4/BoruvkaMST.class
package edu.princeton.cs.algs4;
public synchronized class BoruvkaMST {
private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private Bag mst;
private double weight;
public void BoruvkaMST(EdgeWeightedGraph);
public Iterable edges();
public double weight();
private static boolean less(Edge, Edge);
private boolean check(EdgeWeightedGraph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BoyerMoore.class
package edu.princeton.cs.algs4;
public synchronized class BoyerMoore {
private final int R;
private int[] right;
private char[] pattern;
private String pat;
public void BoyerMoore(String);
public void BoyerMoore(char[], int);
public int search(String);
public int search(char[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/BreadthFirstDirectedPaths.class
package edu.princeton.cs.algs4;
public synchronized class BreadthFirstDirectedPaths {
private static final int INFINITY = 2147483647;
private boolean[] marked;
private int[] edgeTo;
private int[] distTo;
public void BreadthFirstDirectedPaths(Digraph, int);
public void BreadthFirstDirectedPaths(Digraph, Iterable);
private void bfs(Digraph, int);
private void bfs(Digraph, Iterable);
public boolean hasPathTo(int);
public int distTo(int);
public Iterable pathTo(int);
private void validateVertex(int);
private void validateVertices(Iterable);
public static void main(String[]);
}

edu/princeton/cs/algs4/BreadthFirstPaths.class
package edu.princeton.cs.algs4;
public synchronized class BreadthFirstPaths {
private static final int INFINITY = 2147483647;
private boolean[] marked;
private int[] edgeTo;
private int[] distTo;
public void BreadthFirstPaths(Graph, int);
public void BreadthFirstPaths(Graph, Iterable);
private void bfs(Graph, int);
private void bfs(Graph, Iterable);
public boolean hasPathTo(int);
public int distTo(int);
public Iterable pathTo(int);
private boolean check(Graph, int);
private void validateVertex(int);
private void validateVertices(Iterable);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BST.class
package edu.princeton.cs.algs4;
public synchronized class BST {
private BST$Node root;
public void BST();
public boolean isEmpty();
public int size();
private int size(BST$Node);
public boolean contains(Comparable);
public Object get(Comparable);
private Object get(BST$Node, Comparable);
public void put(Comparable, Object);
private BST$Node put(BST$Node, Comparable, Object);
public void deleteMin();
private BST$Node deleteMin(BST$Node);
public void deleteMax();
private BST$Node deleteMax(BST$Node);
public void delete(Comparable);
private BST$Node delete(BST$Node, Comparable);
public Comparable min();
private BST$Node min(BST$Node);
public Comparable max();
private BST$Node max(BST$Node);
public Comparable floor(Comparable);
private BST$Node floor(BST$Node, Comparable);
public Comparable floor2(Comparable);
private Comparable floor2(BST$Node, Comparable, Comparable);
public Comparable ceiling(Comparable);
private BST$Node ceiling(BST$Node, Comparable);
public Comparable select(int);
private BST$Node select(BST$Node, int);
public int rank(Comparable);
private int rank(Comparable, BST$Node);
public Iterable keys();
public Iterable keys(Comparable, Comparable);
private void keys(BST$Node, Queue, Comparable, Comparable);
public int size(Comparable, Comparable);
public int height();
private int height(BST$Node);
public Iterable levelOrder();
private boolean check();
private boolean isBST();
private boolean isBST(BST$Node, Comparable, Comparable);
private boolean isSizeConsistent();
private boolean isSizeConsistent(BST$Node);
private boolean isRankConsistent();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/BST$Node.class
package edu.princeton.cs.algs4;
synchronized class BST$Node {
private Comparable key;
private Object val;
private BST$Node left;
private BST$Node right;
private int size;
public void BST$Node(BST, Comparable, Object, int);
}

edu/princeton/cs/algs4/BTree$1.class
package edu.princeton.cs.algs4;
synchronized class BTree$1 {
}

edu/princeton/cs/algs4/BTree.class
package edu.princeton.cs.algs4;
public synchronized class BTree {
private static final int M = 4;
private BTree$Node root;
private int height;
private int n;
public void BTree();
public boolean isEmpty();
public int size();
public int height();
public Object get(Comparable);
private Object search(BTree$Node, Comparable, int);
public void put(Comparable, Object);
private BTree$Node insert(BTree$Node, Comparable, Object, int);
private BTree$Node split(BTree$Node);
public String toString();
private String toString(BTree$Node, int, String);
private boolean less(Comparable, Comparable);
private boolean eq(Comparable, Comparable);
public static void main(String[]);
}

edu/princeton/cs/algs4/BTree$Entry.class
package edu.princeton.cs.algs4;
synchronized class BTree$Entry {
private Comparable key;
private final Object val;
private BTree$Node next;
public void BTree$Entry(Comparable, Object, BTree$Node);
}

edu/princeton/cs/algs4/BTree$Node.class
package edu.princeton.cs.algs4;
final synchronized class BTree$Node {
private int m;
private BTree$Entry[] children;
private void BTree$Node(int);
}

edu/princeton/cs/algs4/Cat.class
package edu.princeton.cs.algs4;
public synchronized class Cat {
private void Cat();
public static void main(String[]);
}

edu/princeton/cs/algs4/CC.class
package edu.princeton.cs.algs4;
public synchronized class CC {
private boolean[] marked;
private int[] id;
private int[] size;
private int count;
public void CC(Graph);
public void CC(EdgeWeightedGraph);
private void dfs(Graph, int);
private void dfs(EdgeWeightedGraph, int);
public int id(int);
public int size(int);
public int count();
public boolean connected(int, int);
public boolean areConnected(int, int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/ClosestPair.class
package edu.princeton.cs.algs4;
public synchronized class ClosestPair {
private Point2D best1;
private Point2D best2;
private double bestDistance;
public void ClosestPair(Point2D[]);
private double closest(Point2D[], Point2D[], Point2D[], int, int);
public Point2D either();
public Point2D other();
public double distance();
private static boolean less(Comparable, Comparable);
private static void merge(Comparable[], Comparable[], int, int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/CollisionSystem.class
package edu.princeton.cs.algs4;
public synchronized class CollisionSystem {
private static final double HZ = 0.5;
private MinPQ pq;
private double t;
private Particle[] particles;
public void CollisionSystem(Particle[]);
private void predict(Particle, double);
private void redraw(double);
public void simulate(double);
public static void main(String[]);
}

edu/princeton/cs/algs4/CollisionSystem$Event.class
package edu.princeton.cs.algs4;
synchronized class CollisionSystem$Event implements Comparable {
private final double time;
private final Particle a;
private final Particle b;
private final int countA;
private final int countB;
public void CollisionSystem$Event(double, Particle, Particle);
public int compareTo(CollisionSystem$Event);
public boolean isValid();
}

edu/princeton/cs/algs4/Complex.class
package edu.princeton.cs.algs4;
public synchronized class Complex {
private final double re;
private final double im;
public void Complex(double, double);
public String toString();
public double abs();
public double phase();
public Complex plus(Complex);
public Complex minus(Complex);
public Complex times(Complex);
public Complex scale(double);
public Complex times(double);
public Complex conjugate();
public Complex reciprocal();
public double re();
public double im();
public Complex divides(Complex);
public Complex exp();
public Complex sin();
public Complex cos();
public Complex tan();
public static void main(String[]);
}

edu/princeton/cs/algs4/Count.class
package edu.princeton.cs.algs4;
public synchronized class Count {
private void Count();
public static void main(String[]);
}

edu/princeton/cs/algs4/Counter.class
package edu.princeton.cs.algs4;
public synchronized class Counter implements Comparable {
private final String name;
private int count;
public void Counter(String);
public void increment();
public int tally();
public String toString();
public int compareTo(Counter);
public static void main(String[]);
}

edu/princeton/cs/algs4/CPM.class
package edu.princeton.cs.algs4;
public synchronized class CPM {
private void CPM();
public static void main(String[]);
}

edu/princeton/cs/algs4/Cycle.class
package edu.princeton.cs.algs4;
public synchronized class Cycle {
private boolean[] marked;
private int[] edgeTo;
private Stack cycle;
public void Cycle(Graph);
private boolean hasSelfLoop(Graph);
private boolean hasParallelEdges(Graph);
public boolean hasCycle();
public Iterable cycle();
private void dfs(Graph, int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Date.class
package edu.princeton.cs.algs4;
public synchronized class Date implements Comparable {
private static final int[] DAYS;
private final int month;
private final int day;
private final int year;
public void Date(int, int, int);
public void Date(String);
public int month();
public int day();
public int year();
private static boolean isValid(int, int, int);
private static boolean isLeapYear(int);
public Date next();
public boolean isAfter(Date);
public boolean isBefore(Date);
public int compareTo(Date);
public String toString();
public boolean equals(Object);
public int hashCode();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DeDup.class
package edu.princeton.cs.algs4;
public synchronized class DeDup {
private void DeDup();
public static void main(String[]);
}

edu/princeton/cs/algs4/DegreesOfSeparation.class
package edu.princeton.cs.algs4;
public synchronized class DegreesOfSeparation {
private void DegreesOfSeparation();
public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstDirectedPaths.class
package edu.princeton.cs.algs4;
public synchronized class DepthFirstDirectedPaths {
private boolean[] marked;
private int[] edgeTo;
private final int s;
public void DepthFirstDirectedPaths(Digraph, int);
private void dfs(Digraph, int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstOrder.class
package edu.princeton.cs.algs4;
public synchronized class DepthFirstOrder {
private boolean[] marked;
private int[] pre;
private int[] post;
private Queue preorder;
private Queue postorder;
private int preCounter;
private int postCounter;
public void DepthFirstOrder(Digraph);
public void DepthFirstOrder(EdgeWeightedDigraph);
private void dfs(Digraph, int);
private void dfs(EdgeWeightedDigraph, int);
public int pre(int);
public int post(int);
public Iterable post();
public Iterable pre();
public Iterable reversePost();
private boolean check();
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DepthFirstPaths.class
package edu.princeton.cs.algs4;
public synchronized class DepthFirstPaths {
private boolean[] marked;
private int[] edgeTo;
private final int s;
public void DepthFirstPaths(Graph, int);
private void dfs(Graph, int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstSearch.class
package edu.princeton.cs.algs4;
public synchronized class DepthFirstSearch {
private boolean[] marked;
private int count;
public void DepthFirstSearch(Graph, int);
private void dfs(Graph, int);
public boolean marked(int);
public int count();
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Digraph.class
package edu.princeton.cs.algs4;
public synchronized class Digraph {
private static final String NEWLINE;
private final int V;
private int E;
private Bag[] adj;
private int[] indegree;
public void Digraph(int);
public void Digraph(In);
public void Digraph(Digraph);
public int V();
public int E();
private void validateVertex(int);
public void addEdge(int, int);
public Iterable adj(int);
public int outdegree(int);
public int indegree(int);
public Digraph reverse();
public String toString();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DigraphGenerator$1.class
package edu.princeton.cs.algs4;
synchronized class DigraphGenerator$1 {
}

edu/princeton/cs/algs4/DigraphGenerator.class
package edu.princeton.cs.algs4;
public synchronized class DigraphGenerator {
private void DigraphGenerator();
public static Digraph simple(int, int);
public static Digraph simple(int, double);
public static Digraph complete(int);
public static Digraph dag(int, int);
public static Digraph tournament(int);
public static Digraph completeRootedInDAG(int);
public static Digraph rootedInDAG(int, int);
public static Digraph completeRootedOutDAG(int);
public static Digraph rootedOutDAG(int, int);
public static Digraph rootedInTree(int);
public static Digraph rootedOutTree(int);
public static Digraph path(int);
public static Digraph binaryTree(int);
public static Digraph cycle(int);
public static Digraph eulerianCycle(int, int);
public static Digraph eulerianPath(int, int);
public static Digraph strong(int, int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/DigraphGenerator$Edge.class
package edu.princeton.cs.algs4;
final synchronized class DigraphGenerator$Edge implements Comparable {
private final int v;
private final int w;
private void DigraphGenerator$Edge(int, int);
public int compareTo(DigraphGenerator$Edge);
}

edu/princeton/cs/algs4/DijkstraAllPairsSP.class
package edu.princeton.cs.algs4;
public synchronized class DijkstraAllPairsSP {
private DijkstraSP[] all;
public void DijkstraAllPairsSP(EdgeWeightedDigraph);
public Iterable path(int, int);
public boolean hasPath(int, int);
public double dist(int, int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/DijkstraSP.class
package edu.princeton.cs.algs4;
public synchronized class DijkstraSP {
private double[] distTo;
private DirectedEdge[] edgeTo;
private IndexMinPQ pq;
public void DijkstraSP(EdgeWeightedDigraph, int);
private void relax(DirectedEdge);
public double distTo(int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private boolean check(EdgeWeightedDigraph, int);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DijkstraUndirectedSP.class
package edu.princeton.cs.algs4;
public synchronized class DijkstraUndirectedSP {
private double[] distTo;
private Edge[] edgeTo;
private IndexMinPQ pq;
public void DijkstraUndirectedSP(EdgeWeightedGraph, int);
private void relax(Edge, int);
public double distTo(int);
public boolean hasPathTo(int);
public Iterable pathTo(int);
private boolean check(EdgeWeightedGraph, int);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DirectedCycle.class
package edu.princeton.cs.algs4;
public synchronized class DirectedCycle {
private boolean[] marked;
private int[] edgeTo;
private boolean[] onStack;
private Stack cycle;
public void DirectedCycle(Digraph);
private void dfs(Digraph, int);
public boolean hasCycle();
public Iterable cycle();
private boolean check();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DirectedCycleX.class
package edu.princeton.cs.algs4;
public synchronized class DirectedCycleX {
private Stack cycle;
public void DirectedCycleX(Digraph);
public Iterable cycle();
public boolean hasCycle();
private boolean check();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DirectedDFS.class
package edu.princeton.cs.algs4;
public synchronized class DirectedDFS {
private boolean[] marked;
private int count;
public void DirectedDFS(Digraph, int);
public void DirectedDFS(Digraph, Iterable);
private void dfs(Digraph, int);
public boolean marked(int);
public int count();
private void validateVertex(int);
private void validateVertices(Iterable);
public static void main(String[]);
}

edu/princeton/cs/algs4/DirectedEdge.class
package edu.princeton.cs.algs4;
public synchronized class DirectedEdge {
private final int v;
private final int w;
private final double weight;
public void DirectedEdge(int, int, double);
public int from();
public int to();
public double weight();
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/DirectedEulerianCycle.class
package edu.princeton.cs.algs4;
public synchronized class DirectedEulerianCycle {
private Stack cycle;
public void DirectedEulerianCycle(Digraph);
public Iterable cycle();
public boolean hasEulerianCycle();
private static int nonIsolatedVertex(Digraph);
private static boolean satisfiesNecessaryAndSufficientConditions(Digraph);
private boolean certifySolution(Digraph);
private static void unitTest(Digraph, String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DirectedEulerianPath.class
package edu.princeton.cs.algs4;
public synchronized class DirectedEulerianPath {
private Stack path;
public void DirectedEulerianPath(Digraph);
public Iterable path();
public boolean hasEulerianPath();
private static int nonIsolatedVertex(Digraph);
private static boolean satisfiesNecessaryAndSufficientConditions(Digraph);
private boolean check(Digraph);
private static void unitTest(Digraph, String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DoublingRatio.class
package edu.princeton.cs.algs4;
public synchronized class DoublingRatio {
private static final int MAXIMUM_INTEGER = 1000000;
private void DoublingRatio();
public static double timeTrial(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/DoublingTest.class
package edu.princeton.cs.algs4;
public synchronized class DoublingTest {
private static final int MAXIMUM_INTEGER = 1000000;
private void DoublingTest();
public static double timeTrial(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Draw.class
package edu.princeton.cs.algs4;
public final synchronized class Draw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
public static final java.awt.Color BLACK;
public static final java.awt.Color BLUE;
public static final java.awt.Color CYAN;
public static final java.awt.Color DARK_GRAY;
public static final java.awt.Color GRAY;
public static final java.awt.Color GREEN;
public static final java.awt.Color LIGHT_GRAY;
public static final java.awt.Color MAGENTA;
public static final java.awt.Color ORANGE;
public static final java.awt.Color PINK;
public static final java.awt.Color RED;
public static final java.awt.Color WHITE;
public static final java.awt.Color YELLOW;
public static final java.awt.Color BOOK_BLUE;
public static final java.awt.Color BOOK_LIGHT_BLUE;
public static final java.awt.Color BOOK_RED;
public static final java.awt.Color PRINCETON_ORANGE;
private static final java.awt.Color DEFAULT_PEN_COLOR;
private static final java.awt.Color DEFAULT_CLEAR_COLOR;
private static final double BORDER = 0.0;
private static final double DEFAULT_XMIN = 0.0;
private static final double DEFAULT_XMAX = 1.0;
private static final double DEFAULT_YMIN = 0.0;
private static final double DEFAULT_YMAX = 1.0;
private static final int DEFAULT_SIZE = 512;
private static final double DEFAULT_PEN_RADIUS = 0.002;
private static final java.awt.Font DEFAULT_FONT;
private java.awt.Color penColor;
private int width;
private int height;
private double penRadius;
private boolean defer;
private double xmin;
private double ymin;
private double xmax;
private double ymax;
private String name;
private final Object mouseLock;
private final Object keyLock;
private java.awt.Font font;
private javax.swing.JLabel draw;
private java.awt.image.BufferedImage offscreenImage;
private java.awt.image.BufferedImage onscreenImage;
private java.awt.Graphics2D offscreen;
private java.awt.Graphics2D onscreen;
private javax.swing.JFrame frame;
private boolean isMousePressed;
private double mouseX;
private double mouseY;
private final java.util.LinkedList keysTyped;
private final java.util.TreeSet keysDown;
private final java.util.ArrayList listeners;
public void Draw(String);
public void Draw();
private void init();
public void setLocationOnScreen(int, int);
public void setDefaultCloseOperation(int);
public void setCanvasSize(int, int);
private javax.swing.JMenuBar createMenuBar();
private static void validate(double, String);
private static void validateNonnegative(double, String);
private static void validateNotNull(Object, String);
public void setXscale();
public void setYscale();
public void setXscale(double, double);
public void setYscale(double, double);
private double scaleX(double);
private double scaleY(double);
private double factorX(double);
private double factorY(double);
private double userX(double);
private double userY(double);
public void clear();
public void clear(java.awt.Color);
public double getPenRadius();
public void setPenRadius();
public void setPenRadius(double);
public java.awt.Color getPenColor();
public void setPenColor();
public void setPenColor(java.awt.Color);
public void setPenColor(int, int, int);
public void xorOn();
public void xorOff();
public javax.swing.JLabel getJLabel();
public java.awt.Font getFont();
public void setFont();
public void setFont(java.awt.Font);
public void line(double, double, double, double);
private void pixel(double, double);
public void point(double, double);
public void circle(double, double, double);
public void filledCircle(double, double, double);
public void ellipse(double, double, double, double);
public void filledEllipse(double, double, double, double);
public void arc(double, double, double, double, double);
public void square(double, double, double);
public void filledSquare(double, double, double);
public void rectangle(double, double, double, double);
public void filledRectangle(double, double, double, double);
public void polygon(double[], double[]);
public void filledPolygon(double[], double[]);
private static java.awt.Image getImage(String);
public void picture(double, double, String);
public void picture(double, double, String, double);
public void picture(double, double, String, double, double);
public void picture(double, double, String, double, double, double);
public void text(double, double, String);
public void text(double, double, String, double);
public void textLeft(double, double, String);
public void textRight(double, double, String);
public void show(int);
public void pause(int);
public void show();
private void draw();
public void enableDoubleBuffering();
public void disableDoubleBuffering();
public void save(String);
public void actionPerformed(java.awt.event.ActionEvent);
public void addListener(DrawListener);
public boolean isMousePressed();
public boolean mousePressed();
public double mouseX();
public double mouseY();
public void mouseEntered(java.awt.event.MouseEvent);
public void mouseExited(java.awt.event.MouseEvent);
public void mousePressed(java.awt.event.MouseEvent);
public void mouseReleased(java.awt.event.MouseEvent);
public void mouseClicked(java.awt.event.MouseEvent);
public void mouseDragged(java.awt.event.MouseEvent);
public void mouseMoved(java.awt.event.MouseEvent);
public boolean hasNextKeyTyped();
public char nextKeyTyped();
public boolean isKeyPressed(int);
public void keyTyped(java.awt.event.KeyEvent);
public void keyPressed(java.awt.event.KeyEvent);
public void keyReleased(java.awt.event.KeyEvent);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/DrawListener.class
package edu.princeton.cs.algs4;
public abstract interface DrawListener {
public abstract void mousePressed(double, double);
public abstract void mouseDragged(double, double);
public abstract void mouseReleased(double, double);
public abstract void mouseClicked(double, double);
public abstract void keyTyped(char);
public abstract void keyPressed(int);
public abstract void keyReleased(int);
}

edu/princeton/cs/algs4/Draw$RetinaImageIcon.class
package edu.princeton.cs.algs4;
synchronized class Draw$RetinaImageIcon extends javax.swing.ImageIcon {
public void Draw$RetinaImageIcon(java.awt.Image);
public int getIconWidth();
public int getIconHeight();
public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

edu/princeton/cs/algs4/Edge.class
package edu.princeton.cs.algs4;
public synchronized class Edge implements Comparable {
private final int v;
private final int w;
private final double weight;
public void Edge(int, int, double);
public double weight();
public int either();
public int other(int);
public int compareTo(Edge);
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/EdgeWeightedDigraph.class
package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedDigraph {
private static final String NEWLINE;
private final int V;
private int E;
private Bag[] adj;
private int[] indegree;
public void EdgeWeightedDigraph(int);
public void EdgeWeightedDigraph(int, int);
public void EdgeWeightedDigraph(In);
public void EdgeWeightedDigraph(EdgeWeightedDigraph);
public int V();
public int E();
private void validateVertex(int);
public void addEdge(DirectedEdge);
public Iterable adj(int);
public int outdegree(int);
public int indegree(int);
public Iterable edges();
public String toString();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.class
package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedDirectedCycle {
private boolean[] marked;
private DirectedEdge[] edgeTo;
private boolean[] onStack;
private Stack cycle;
public void EdgeWeightedDirectedCycle(EdgeWeightedDigraph);
private void dfs(EdgeWeightedDigraph, int);
public boolean hasCycle();
public Iterable cycle();
private boolean check();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/EdgeWeightedGraph.class
package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedGraph {
private static final String NEWLINE;
private final int V;
private int E;
private Bag[] adj;
public void EdgeWeightedGraph(int);
public void EdgeWeightedGraph(int, int);
public void EdgeWeightedGraph(In);
public void EdgeWeightedGraph(EdgeWeightedGraph);
public int V();
public int E();
private void validateVertex(int);
public void addEdge(Edge);
public Iterable adj(int);
public int degree(int);
public Iterable edges();
public String toString();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/EulerianCycle.class
package edu.princeton.cs.algs4;
public synchronized class EulerianCycle {
private Stack cycle;
public void EulerianCycle(Graph);
public Iterable cycle();
public boolean hasEulerianCycle();
private static int nonIsolatedVertex(Graph);
private static boolean satisfiesNecessaryAndSufficientConditions(Graph);
private boolean certifySolution(Graph);
private static void unitTest(Graph, String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/EulerianCycle$Edge.class
package edu.princeton.cs.algs4;
synchronized class EulerianCycle$Edge {
private final int v;
private final int w;
private boolean isUsed;
public void EulerianCycle$Edge(int, int);
public int other(int);
}

edu/princeton/cs/algs4/EulerianPath.class
package edu.princeton.cs.algs4;
public synchronized class EulerianPath {
private Stack path;
public void EulerianPath(Graph);
public Iterable path();
public boolean hasEulerianPath();
private static int nonIsolatedVertex(Graph);
private static boolean satisfiesNecessaryAndSufficientConditions(Graph);
private boolean certifySolution(Graph);
private static void unitTest(Graph, String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/EulerianPath$Edge.class
package edu.princeton.cs.algs4;
synchronized class EulerianPath$Edge {
private final int v;
private final int w;
private boolean isUsed;
public void EulerianPath$Edge(int, int);
public int other(int);
}

edu/princeton/cs/algs4/FarthestPair.class
package edu.princeton.cs.algs4;
public synchronized class FarthestPair {
private Point2D best1;
private Point2D best2;
private double bestDistanceSquared;
public void FarthestPair(Point2D[]);
public Point2D either();
public Point2D other();
public double distance();
public static void main(String[]);
}

edu/princeton/cs/algs4/FenwickTree.class
package edu.princeton.cs.algs4;
public synchronized class FenwickTree {
int[] array;
public void FenwickTree(int);
public int rsq(int);
public int rsq(int, int);
public void update(int, int);
public int size();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/FFT.class
package edu.princeton.cs.algs4;
public synchronized class FFT {
private static final Complex ZERO;
private void FFT();
public static Complex[] fft(Complex[]);
public static Complex[] ifft(Complex[]);
public static Complex[] cconvolve(Complex[], Complex[]);
public static Complex[] convolve(Complex[], Complex[]);
private static void show(Complex[], String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/FibonacciMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$1 {
}

edu/princeton/cs/algs4/FibonacciMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class FibonacciMinPQ implements Iterable {
private FibonacciMinPQ$Node head;
private FibonacciMinPQ$Node min;
private int size;
private final java.util.Comparator comp;
private java.util.HashMap table;
public void FibonacciMinPQ(java.util.Comparator);
public void FibonacciMinPQ();
public void FibonacciMinPQ(Object[]);
public void FibonacciMinPQ(java.util.Comparator, Object[]);
public boolean isEmpty();
public int size();
public void insert(Object);
public Object minKey();
public Object delMin();
public FibonacciMinPQ union(FibonacciMinPQ);
private boolean greater(Object, Object);
private void link(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
private void consolidate();
private FibonacciMinPQ$Node insert(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
private FibonacciMinPQ$Node cut(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
private FibonacciMinPQ$Node meld(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/FibonacciMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$MyComparator implements java.util.Comparator {
private void FibonacciMinPQ$MyComparator(FibonacciMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/FibonacciMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$MyIterator implements java.util.Iterator {
private FibonacciMinPQ copy;
public void FibonacciMinPQ$MyIterator(FibonacciMinPQ);
private void insertAll(FibonacciMinPQ$Node);
public void remove();
public boolean hasNext();
public Object next();
}

edu/princeton/cs/algs4/FibonacciMinPQ$Node.class
package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$Node {
Object key;
int order;
FibonacciMinPQ$Node prev;
FibonacciMinPQ$Node next;
FibonacciMinPQ$Node child;
private void FibonacciMinPQ$Node(FibonacciMinPQ);
}

edu/princeton/cs/algs4/FileIndex.class
package edu.princeton.cs.algs4;
public synchronized class FileIndex {
private void FileIndex();
public static void main(String[]);
}

edu/princeton/cs/algs4/FlowEdge.class
package edu.princeton.cs.algs4;
public synchronized class FlowEdge {
private static final double FLOATING_POINT_EPSILON = 1.0E-10;
private final int v;
private final int w;
private final double capacity;
private double flow;
public void FlowEdge(int, int, double);
public void FlowEdge(int, int, double, double);
public void FlowEdge(FlowEdge);
public int from();
public int to();
public double capacity();
public double flow();
public int other(int);
public double residualCapacityTo(int);
public void addResidualFlowTo(int, double);
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/FlowNetwork.class
package edu.princeton.cs.algs4;
public synchronized class FlowNetwork {
private static final String NEWLINE;
private final int V;
private int E;
private Bag[] adj;
public void FlowNetwork(int);
public void FlowNetwork(int, int);
public void FlowNetwork(In);
public int V();
public int E();
private void validateVertex(int);
public void addEdge(FlowEdge);
public Iterable adj(int);
public Iterable edges();
public String toString();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/FloydWarshall.class
package edu.princeton.cs.algs4;
public synchronized class FloydWarshall {
private boolean hasNegativeCycle;
private double[][] distTo;
private DirectedEdge[][] edgeTo;
public void FloydWarshall(AdjMatrixEdgeWeightedDigraph);
public boolean hasNegativeCycle();
public Iterable negativeCycle();
public boolean hasPath(int, int);
public double dist(int, int);
public Iterable path(int, int);
private boolean check(AdjMatrixEdgeWeightedDigraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/FordFulkerson.class
package edu.princeton.cs.algs4;
public synchronized class FordFulkerson {
private static final double FLOATING_POINT_EPSILON = 1.0E-11;
private final int V;
private boolean[] marked;
private FlowEdge[] edgeTo;
private double value;
public void FordFulkerson(FlowNetwork, int, int);
public double value();
public boolean inCut(int);
private void validate(int);
private boolean hasAugmentingPath(FlowNetwork, int, int);
private double excess(FlowNetwork, int);
private boolean isFeasible(FlowNetwork, int, int);
private boolean check(FlowNetwork, int, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/FrequencyCounter.class
package edu.princeton.cs.algs4;
public synchronized class FrequencyCounter {
private void FrequencyCounter();
public static void main(String[]);
}

edu/princeton/cs/algs4/GabowSCC.class
package edu.princeton.cs.algs4;
public synchronized class GabowSCC {
private boolean[] marked;
private int[] id;
private int[] preorder;
private int pre;
private int count;
private Stack stack1;
private Stack stack2;
public void GabowSCC(Digraph);
private void dfs(Digraph, int);
public int count();
public boolean stronglyConnected(int, int);
public int id(int);
private boolean check(Digraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/GaussianElimination.class
package edu.princeton.cs.algs4;
public synchronized class GaussianElimination {
private static final double EPSILON = 1.0E-8;
private final int m;
private final int n;
private double[][] a;
public void GaussianElimination(double[][], double[]);
private void forwardElimination();
private void swap(int, int);
private void pivot(int);
public double[] primal();
public boolean isFeasible();
private boolean certifySolution(double[][], double[]);
private static void test(String, double[][], double[]);
private static void test1();
private static void test2();
private static void test3();
private static void test4();
private static void test5();
private static void test6();
private static void test7();
private static void test8();
private static void test9();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/GaussJordanElimination.class
package edu.princeton.cs.algs4;
public synchronized class GaussJordanElimination {
private static final double EPSILON = 1.0E-8;
private final int n;
private double[][] a;
public void GaussJordanElimination(double[][], double[]);
private void solve();
private void swap(int, int);
private void pivot(int, int);
public double[] primal();
public double[] dual();
public boolean isFeasible();
private void show();
private boolean certifySolution(double[][], double[]);
private static void test(String, double[][], double[]);
private static void test1();
private static void test2();
private static void test3();
private static void test4();
private static void test5();
private static void test6();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Genome.class
package edu.princeton.cs.algs4;
public synchronized class Genome {
private void Genome();
public static void compress();
public static void expand();
public static void main(String[]);
}

edu/princeton/cs/algs4/GlobalMincut.class
package edu.princeton.cs.algs4;
public synchronized class GlobalMincut {
private static final double FLOATING_POINT_EPSILON = 1.0E-11;
private double weight;
private boolean[] cut;
private int V;
public void GlobalMincut(EdgeWeightedGraph);
private void validate(EdgeWeightedGraph);
public double weight();
public boolean cut(int);
private void makeCut(int, UF);
private void minCut(EdgeWeightedGraph, int);
private GlobalMincut$CutPhase minCutPhase(EdgeWeightedGraph, boolean[], GlobalMincut$CutPhase);
private EdgeWeightedGraph contractEdge(EdgeWeightedGraph, int, int);
private boolean check(EdgeWeightedGraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/GlobalMincut$CutPhase.class
package edu.princeton.cs.algs4;
synchronized class GlobalMincut$CutPhase {
private double weight;
private int s;
private int t;
public void GlobalMincut$CutPhase(GlobalMincut, double, int, int);
}

edu/princeton/cs/algs4/GrahamScan.class
package edu.princeton.cs.algs4;
public synchronized class GrahamScan {
private Stack hull;
public void GrahamScan(Point2D[]);
public Iterable hull();
private boolean isConvex();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Graph.class
package edu.princeton.cs.algs4;
public synchronized class Graph {
private static final String NEWLINE;
private final int V;
private int E;
private Bag[] adj;
public void Graph(int);
public void Graph(In);
public void Graph(Graph);
public int V();
public int E();
private void validateVertex(int);
public void addEdge(int, int);
public Iterable adj(int);
public int degree(int);
public String toString();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/GraphGenerator$1.class
package edu.princeton.cs.algs4;
synchronized class GraphGenerator$1 {
}

edu/princeton/cs/algs4/GraphGenerator.class
package edu.princeton.cs.algs4;
public synchronized class GraphGenerator {
private void GraphGenerator();
public static Graph simple(int, int);
public static Graph simple(int, double);
public static Graph complete(int);
public static Graph completeBipartite(int, int);
public static Graph bipartite(int, int, int);
public static Graph bipartite(int, int, double);
public static Graph path(int);
public static Graph binaryTree(int);
public static Graph cycle(int);
public static Graph eulerianCycle(int, int);
public static Graph eulerianPath(int, int);
public static Graph wheel(int);
public static Graph star(int);
public static Graph regular(int, int);
public static Graph tree(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/GraphGenerator$Edge.class
package edu.princeton.cs.algs4;
final synchronized class GraphGenerator$Edge implements Comparable {
private int v;
private int w;
private void GraphGenerator$Edge(int, int);
public int compareTo(GraphGenerator$Edge);
}

edu/princeton/cs/algs4/GrayscalePicture.class
package edu.princeton.cs.algs4;
public final synchronized class GrayscalePicture implements java.awt.event.ActionListener {
private java.awt.image.BufferedImage image;
private javax.swing.JFrame frame;
private String filename;
private boolean isOriginUpperLeft;
private final int width;
private final int height;
public void GrayscalePicture(int, int);
public void GrayscalePicture(GrayscalePicture);
public void GrayscalePicture(String);
private static java.awt.Color toGray(java.awt.Color);
public javax.swing.JLabel getJLabel();
public void setOriginUpperLeft();
public void setOriginLowerLeft();
public void show();
public int height();
public int width();
private void validateRowIndex(int);
private void validateColumnIndex(int);
private void validateGrayscaleValue(int);
public java.awt.Color get(int, int);
public int getGrayscale(int, int);
public void set(int, int, java.awt.Color);
public void setGrayscale(int, int, int);
public boolean equals(Object);
public String toString();
public int hashCode();
public void save(String);
public void save(java.io.File);
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
}

edu/princeton/cs/algs4/GREP.class
package edu.princeton.cs.algs4;
public synchronized class GREP {
private void GREP();
public static void main(String[]);
}

edu/princeton/cs/algs4/Heap.class
package edu.princeton.cs.algs4;
public synchronized class Heap {
private void Heap();
public static void sort(Comparable[]);
private static void sink(Comparable[], int, int);
private static boolean less(Comparable[], int, int);
private static void exch(Object[], int, int);
private static void show(Comparable[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/HexDump.class
package edu.princeton.cs.algs4;
public synchronized class HexDump {
private void HexDump();
public static void main(String[]);
}

edu/princeton/cs/algs4/HopcroftKarp.class
package edu.princeton.cs.algs4;
public synchronized class HopcroftKarp {
private static final int UNMATCHED = -1;
private final int V;
private BipartiteX bipartition;
private int cardinality;
private int[] mate;
private boolean[] inMinVertexCover;
private boolean[] marked;
private int[] distTo;
public void HopcroftKarp(Graph);
private static String toString(Iterable);
private boolean isLevelGraphEdge(int, int);
private boolean isResidualGraphEdge(int, int);
private boolean hasAugmentingPath(Graph);
public int mate(int);
public boolean isMatched(int);
public int size();
public boolean isPerfect();
public boolean inMinVertexCover(int);
private void validate(int);
private boolean certifySolution(Graph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Huffman.class
package edu.princeton.cs.algs4;
public synchronized class Huffman {
private static final int R = 256;
private void Huffman();
public static void compress();
private static Huffman$Node buildTrie(int[]);
private static void writeTrie(Huffman$Node);
private static void buildCode(String[], Huffman$Node, String);
public static void expand();
private static Huffman$Node readTrie();
public static void main(String[]);
}

edu/princeton/cs/algs4/Huffman$Node.class
package edu.princeton.cs.algs4;
synchronized class Huffman$Node implements Comparable {
private final char ch;
private final int freq;
private final Huffman$Node left;
private final Huffman$Node right;
void Huffman$Node(char, int, Huffman$Node, Huffman$Node);
private boolean isLeaf();
public int compareTo(Huffman$Node);
static void ();
}

edu/princeton/cs/algs4/In.class
package edu.princeton.cs.algs4;
public final synchronized class In {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static final java.util.regex.Pattern WHITESPACE_PATTERN;
private static final java.util.regex.Pattern EMPTY_PATTERN;
private static final java.util.regex.Pattern EVERYTHING_PATTERN;
private java.util.Scanner scanner;
public void In();
public void In(java.net.Socket);
public void In(java.net.URL);
public void In(java.io.File);
public void In(String);
public void In(java.util.Scanner);
public boolean exists();
public boolean isEmpty();
public boolean hasNextLine();
public boolean hasNextChar();
public String readLine();
public char readChar();
public String readAll();
public String readString();
public int readInt();
public double readDouble();
public float readFloat();
public long readLong();
public short readShort();
public byte readByte();
public boolean readBoolean();
public String[] readAllStrings();
public String[] readAllLines();
public int[] readAllInts();
public long[] readAllLongs();
public double[] readAllDoubles();
public void close();
public static int[] readInts(String);
public static double[] readDoubles(String);
public static String[] readStrings(String);
public static int[] readInts();
public static double[] readDoubles();
public static String[] readStrings();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$1 {
}

edu/princeton/cs/algs4/IndexBinomialMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class IndexBinomialMinPQ implements Iterable {
private IndexBinomialMinPQ$Node head;
private IndexBinomialMinPQ$Node[] nodes;
private int n;
private final java.util.Comparator comparator;
public void IndexBinomialMinPQ(int);
public void IndexBinomialMinPQ(int, java.util.Comparator);
public boolean isEmpty();
public boolean contains(int);
public int size();
public void insert(int, Object);
public int minIndex();
public Object minKey();
public int delMin();
public Object keyOf(int);
public void changeKey(int, Object);
public void decreaseKey(int, Object);
public void increaseKey(int, Object);
public void delete(int);
private boolean greater(Object, Object);
private void exchange(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
private void link(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
private void swim(int);
private void toTheRoot(int);
private IndexBinomialMinPQ$Node erase(int);
private IndexBinomialMinPQ$Node eraseMin();
private IndexBinomialMinPQ$Node merge(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
private IndexBinomialMinPQ union(IndexBinomialMinPQ);
private void IndexBinomialMinPQ();
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$MyComparator implements java.util.Comparator {
private void IndexBinomialMinPQ$MyComparator(IndexBinomialMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$MyIterator implements java.util.Iterator {
IndexBinomialMinPQ data;
public void IndexBinomialMinPQ$MyIterator(IndexBinomialMinPQ);
private IndexBinomialMinPQ$Node clone(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
public boolean hasNext();
public Integer next();
public void remove();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$Node.class
package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$Node {
Object key;
int order;
int index;
IndexBinomialMinPQ$Node parent;
IndexBinomialMinPQ$Node child;
IndexBinomialMinPQ$Node sibling;
private void IndexBinomialMinPQ$Node(IndexBinomialMinPQ);
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$1 {
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class IndexFibonacciMinPQ implements Iterable {
private IndexFibonacciMinPQ$Node[] nodes;
private IndexFibonacciMinPQ$Node head;
private IndexFibonacciMinPQ$Node min;
private int size;
private int n;
private final java.util.Comparator comp;
private java.util.HashMap table;
public void IndexFibonacciMinPQ(int);
public void IndexFibonacciMinPQ(java.util.Comparator, int);
public boolean isEmpty();
public boolean contains(int);
public int size();
public void insert(int, Object);
public int minIndex();
public Object minKey();
public int delMin();
public Object keyOf(int);
public void changeKey(int, Object);
public void decreaseKey(int, Object);
public void increaseKey(int, Object);
public void delete(int);
private boolean greater(Object, Object);
private void link(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
private void cut(int);
private void consolidate();
private IndexFibonacciMinPQ$Node insert(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
private IndexFibonacciMinPQ$Node cut(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
private IndexFibonacciMinPQ$Node meld(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$MyComparator implements java.util.Comparator {
private void IndexFibonacciMinPQ$MyComparator(IndexFibonacciMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$MyIterator implements java.util.Iterator {
private IndexFibonacciMinPQ copy;
public void IndexFibonacciMinPQ$MyIterator(IndexFibonacciMinPQ);
public void remove();
public boolean hasNext();
public Integer next();
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$Node.class
package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$Node {
Object key;
int order;
int index;
IndexFibonacciMinPQ$Node prev;
IndexFibonacciMinPQ$Node next;
IndexFibonacciMinPQ$Node parent;
IndexFibonacciMinPQ$Node child;
boolean mark;
private void IndexFibonacciMinPQ$Node(IndexFibonacciMinPQ);
}

edu/princeton/cs/algs4/IndexMaxPQ.class
package edu.princeton.cs.algs4;
public synchronized class IndexMaxPQ implements Iterable {
private int maxN;
private int n;
private int[] pq;
private int[] qp;
private Comparable[] keys;
public void IndexMaxPQ(int);
public boolean isEmpty();
public boolean contains(int);
public int size();
public void insert(int, Comparable);
public int maxIndex();
public Comparable maxKey();
public int delMax();
public Comparable keyOf(int);
public void changeKey(int, Comparable);
public void change(int, Comparable);
public void increaseKey(int, Comparable);
public void decreaseKey(int, Comparable);
public void delete(int);
private void validateIndex(int);
private boolean less(int, int);
private void exch(int, int);
private void swim(int);
private void sink(int);
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/IndexMaxPQ$HeapIterator.class
package edu.princeton.cs.algs4;
synchronized class IndexMaxPQ$HeapIterator implements java.util.Iterator {
private IndexMaxPQ copy;
public void IndexMaxPQ$HeapIterator(IndexMaxPQ);
public boolean hasNext();
public void remove();
public Integer next();
}

edu/princeton/cs/algs4/IndexMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class IndexMinPQ implements Iterable {
private int maxN;
private int n;
private int[] pq;
private int[] qp;
private Comparable[] keys;
public void IndexMinPQ(int);
public boolean isEmpty();
public boolean contains(int);
public int size();
public void insert(int, Comparable);
public int minIndex();
public Comparable minKey();
public int delMin();
public Comparable keyOf(int);
public void changeKey(int, Comparable);
public void change(int, Comparable);
public void decreaseKey(int, Comparable);
public void increaseKey(int, Comparable);
public void delete(int);
private void validateIndex(int);
private boolean greater(int, int);
private void exch(int, int);
private void swim(int);
private void sink(int);
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/IndexMinPQ$HeapIterator.class
package edu.princeton.cs.algs4;
synchronized class IndexMinPQ$HeapIterator implements java.util.Iterator {
private IndexMinPQ copy;
public void IndexMinPQ$HeapIterator(IndexMinPQ);
public boolean hasNext();
public void remove();
public Integer next();
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$1 {
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class IndexMultiwayMinPQ implements Iterable {
private final int d;
private int n;
private int nmax;
private int[] pq;
private int[] qp;
private Object[] keys;
private final java.util.Comparator comp;
public void IndexMultiwayMinPQ(int, int);
public void IndexMultiwayMinPQ(int, java.util.Comparator, int);
public boolean isEmpty();
public boolean contains(int);
public int size();
public void insert(int, Object);
public int minIndex();
public Object minKey();
public int delMin();
public Object keyOf(int);
public void changeKey(int, Object);
public void decreaseKey(int, Object);
public void increaseKey(int, Object);
public void delete(int);
private boolean greater(int, int);
private void exch(int, int);
private void swim(int);
private void sink(int);
private int minChild(int);
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$MyComparator implements java.util.Comparator {
private void IndexMultiwayMinPQ$MyComparator(IndexMultiwayMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$MyIterator implements java.util.Iterator {
IndexMultiwayMinPQ clone;
public void IndexMultiwayMinPQ$MyIterator(IndexMultiwayMinPQ);
public boolean hasNext();
public Integer next();
public void remove();
}

edu/princeton/cs/algs4/InplaceMSD.class
package edu.princeton.cs.algs4;
public synchronized class InplaceMSD {
private static final int R = 256;
private static final int CUTOFF = 15;
private void InplaceMSD();
public static void sort(String[]);
private static int charAt(String, int);
private static void sort(String[], int, int, int);
private static void insertion(String[], int, int, int);
private static void exch(String[], int, int);
private static boolean less(String, String, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Insertion.class
package edu.princeton.cs.algs4;
public synchronized class Insertion {
private void Insertion();
public static void sort(Comparable[]);
public static void sort(Comparable[], int, int);
public static void sort(Object[], java.util.Comparator);
public static void sort(Object[], int, int, java.util.Comparator);
public static int[] indexSort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static boolean less(Object, Object, java.util.Comparator);
private static void exch(Object[], int, int);
private static void exch(int[], int, int);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static boolean isSorted(Object[], java.util.Comparator);
private static boolean isSorted(Object[], int, int, java.util.Comparator);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/InsertionX.class
package edu.princeton.cs.algs4;
public synchronized class InsertionX {
private void InsertionX();
public static void sort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Interval1D$1.class
package edu.princeton.cs.algs4;
synchronized class Interval1D$1 {
}

edu/princeton/cs/algs4/Interval1D.class
package edu.princeton.cs.algs4;
public synchronized class Interval1D {
public static final java.util.Comparator MIN_ENDPOINT_ORDER;
public static final java.util.Comparator MAX_ENDPOINT_ORDER;
public static final java.util.Comparator LENGTH_ORDER;
private final double min;
private final double max;
public void Interval1D(double, double);
public double left();
public double right();
public double min();
public double max();
public boolean intersects(Interval1D);
public boolean contains(double);
public double length();
public String toString();
public boolean equals(Object);
public int hashCode();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Interval1D$LengthComparator.class
package edu.princeton.cs.algs4;
synchronized class Interval1D$LengthComparator implements java.util.Comparator {
private void Interval1D$LengthComparator();
public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval1D$MaxEndpointComparator.class
package edu.princeton.cs.algs4;
synchronized class Interval1D$MaxEndpointComparator implements java.util.Comparator {
private void Interval1D$MaxEndpointComparator();
public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval1D$MinEndpointComparator.class
package edu.princeton.cs.algs4;
synchronized class Interval1D$MinEndpointComparator implements java.util.Comparator {
private void Interval1D$MinEndpointComparator();
public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval2D.class
package edu.princeton.cs.algs4;
public synchronized class Interval2D {
private final Interval1D x;
private final Interval1D y;
public void Interval2D(Interval1D, Interval1D);
public boolean intersects(Interval2D);
public boolean contains(Point2D);
public double area();
public String toString();
public boolean equals(Object);
public int hashCode();
public void draw();
public static void main(String[]);
}

edu/princeton/cs/algs4/Inversions.class
package edu.princeton.cs.algs4;
public synchronized class Inversions {
private void Inversions();
private static long merge(int[], int[], int, int, int);
private static long count(int[], int[], int[], int, int);
public static long count(int[]);
private static long merge(Comparable[], Comparable[], int, int, int);
private static long count(Comparable[], Comparable[], Comparable[], int, int);
public static long count(Comparable[]);
private static boolean less(Comparable, Comparable);
private static long brute(Comparable[], int, int);
private static long brute(int[], int, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/KMP.class
package edu.princeton.cs.algs4;
public synchronized class KMP {
private final int R;
private int[][] dfa;
private char[] pattern;
private String pat;
public void KMP(String);
public void KMP(char[], int);
public int search(String);
public int search(char[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/Knuth.class
package edu.princeton.cs.algs4;
public synchronized class Knuth {
private void Knuth();
public static void shuffle(Object[]);
public static void shuffleAlternate(Object[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/KosarajuSharirSCC.class
package edu.princeton.cs.algs4;
public synchronized class KosarajuSharirSCC {
private boolean[] marked;
private int[] id;
private int count;
public void KosarajuSharirSCC(Digraph);
private void dfs(Digraph, int);
public int count();
public boolean stronglyConnected(int, int);
public int id(int);
private boolean check(Digraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/KruskalMST.class
package edu.princeton.cs.algs4;
public synchronized class KruskalMST {
private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private double weight;
private Queue mst;
public void KruskalMST(EdgeWeightedGraph);
public Iterable edges();
public double weight();
private boolean check(EdgeWeightedGraph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/KWIK.class
package edu.princeton.cs.algs4;
public synchronized class KWIK {
private void KWIK();
public static void main(String[]);
}

edu/princeton/cs/algs4/LazyPrimMST.class
package edu.princeton.cs.algs4;
public synchronized class LazyPrimMST {
private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private double weight;
private Queue mst;
private boolean[] marked;
private MinPQ pq;
public void LazyPrimMST(EdgeWeightedGraph);
private void prim(EdgeWeightedGraph, int);
private void scan(EdgeWeightedGraph, int);
public Iterable edges();
public double weight();
private boolean check(EdgeWeightedGraph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LinearProbingHashST.class
package edu.princeton.cs.algs4;
public synchronized class LinearProbingHashST {
private static final int INIT_CAPACITY = 4;
private int n;
private int m;
private Object[] keys;
private Object[] vals;
public void LinearProbingHashST();
public void LinearProbingHashST(int);
public int size();
public boolean isEmpty();
public boolean contains(Object);
private int hash(Object);
private void resize(int);
public void put(Object, Object);
public Object get(Object);
public void delete(Object);
public Iterable keys();
private boolean check();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LinearProgramming.class
package edu.princeton.cs.algs4;
public synchronized class LinearProgramming {
private static final double EPSILON = 1.0E-10;
private double[][] a;
private int m;
private int n;
private int[] basis;
public void LinearProgramming(double[][], double[], double[]);
private void solve();
private int bland();
private int dantzig();
private int minRatioRule(int);
private void pivot(int, int);
public double value();
public double[] primal();
public double[] dual();
private boolean isPrimalFeasible(double[][], double[]);
private boolean isDualFeasible(double[][], double[]);
private boolean isOptimal(double[], double[]);
private boolean check(double[][], double[], double[]);
private void show();
private static void test(double[][], double[], double[]);
private static void test1();
private static void test2();
private static void test3();
private static void test4();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LinearRegression.class
package edu.princeton.cs.algs4;
public synchronized class LinearRegression {
private final double intercept;
private final double slope;
private final double r2;
private final double svar0;
private final double svar1;
public void LinearRegression(double[], double[]);
public double intercept();
public double slope();
public double R2();
public double interceptStdErr();
public double slopeStdErr();
public double predict(double);
public String toString();
}

edu/princeton/cs/algs4/LinkedBag$1.class
package edu.princeton.cs.algs4;
synchronized class LinkedBag$1 {
}

edu/princeton/cs/algs4/LinkedBag.class
package edu.princeton.cs.algs4;
public synchronized class LinkedBag implements Iterable {
private LinkedBag$Node first;
private int n;
public void LinkedBag();
public boolean isEmpty();
public int size();
public void add(Object);
public java.util.Iterator iterator();
public static void main(String[]);
}

edu/princeton/cs/algs4/LinkedBag$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class LinkedBag$ListIterator implements java.util.Iterator {
private LinkedBag$Node current;
public void LinkedBag$ListIterator(LinkedBag);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/LinkedBag$Node.class
package edu.princeton.cs.algs4;
synchronized class LinkedBag$Node {
private Object item;
private LinkedBag$Node next;
private void LinkedBag$Node(LinkedBag);
}

edu/princeton/cs/algs4/LinkedQueue$1.class
package edu.princeton.cs.algs4;
synchronized class LinkedQueue$1 {
}

edu/princeton/cs/algs4/LinkedQueue.class
package edu.princeton.cs.algs4;
public synchronized class LinkedQueue implements Iterable {
private int n;
private LinkedQueue$Node first;
private LinkedQueue$Node last;
public void LinkedQueue();
public boolean isEmpty();
public int size();
public Object peek();
public void enqueue(Object);
public Object dequeue();
public String toString();
private boolean check();
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LinkedQueue$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class LinkedQueue$ListIterator implements java.util.Iterator {
private LinkedQueue$Node current;
private void LinkedQueue$ListIterator(LinkedQueue);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/LinkedQueue$Node.class
package edu.princeton.cs.algs4;
synchronized class LinkedQueue$Node {
private Object item;
private LinkedQueue$Node next;
private void LinkedQueue$Node(LinkedQueue);
}

edu/princeton/cs/algs4/LinkedStack$1.class
package edu.princeton.cs.algs4;
synchronized class LinkedStack$1 {
}

edu/princeton/cs/algs4/LinkedStack.class
package edu.princeton.cs.algs4;
public synchronized class LinkedStack implements Iterable {
private int n;
private LinkedStack$Node first;
public void LinkedStack();
public boolean isEmpty();
public int size();
public void push(Object);
public Object pop();
public Object peek();
public String toString();
public java.util.Iterator iterator();
private boolean check();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LinkedStack$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class LinkedStack$ListIterator implements java.util.Iterator {
private LinkedStack$Node current;
private void LinkedStack$ListIterator(LinkedStack);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/LinkedStack$Node.class
package edu.princeton.cs.algs4;
synchronized class LinkedStack$Node {
private Object item;
private LinkedStack$Node next;
private void LinkedStack$Node(LinkedStack);
}

edu/princeton/cs/algs4/LongestCommonSubstring.class
package edu.princeton.cs.algs4;
public synchronized class LongestCommonSubstring {
private void LongestCommonSubstring();
private static String lcp(String, int, String, int);
private static int compare(String, int, String, int);
public static String lcs(String, String);
public static void main(String[]);
}

edu/princeton/cs/algs4/LongestRepeatedSubstring.class
package edu.princeton.cs.algs4;
public synchronized class LongestRepeatedSubstring {
private void LongestRepeatedSubstring();
public static String lrs(String);
public static void main(String[]);
}

edu/princeton/cs/algs4/LookupCSV.class
package edu.princeton.cs.algs4;
public synchronized class LookupCSV {
private void LookupCSV();
public static void main(String[]);
}

edu/princeton/cs/algs4/LookupIndex.class
package edu.princeton.cs.algs4;
public synchronized class LookupIndex {
private void LookupIndex();
public static void main(String[]);
}

edu/princeton/cs/algs4/LSD.class
package edu.princeton.cs.algs4;
public synchronized class LSD {
private static final int BITS_PER_BYTE = 8;
private void LSD();
public static void sort(String[], int);
public static void sort(int[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/LZW.class
package edu.princeton.cs.algs4;
public synchronized class LZW {
private static final int R = 256;
private static final int L = 4096;
private static final int W = 12;
private void LZW();
public static void compress();
public static void expand();
public static void main(String[]);
}

edu/princeton/cs/algs4/MaxPQ.class
package edu.princeton.cs.algs4;
public synchronized class MaxPQ implements Iterable {
private Object[] pq;
private int n;
private java.util.Comparator comparator;
public void MaxPQ(int);
public void MaxPQ();
public void MaxPQ(int, java.util.Comparator);
public void MaxPQ(java.util.Comparator);
public void MaxPQ(Object[]);
public boolean isEmpty();
public int size();
public Object max();
private void resize(int);
public void insert(Object);
public Object delMax();
private void swim(int);
private void sink(int);
private boolean less(int, int);
private void exch(int, int);
private boolean isMaxHeap();
private boolean isMaxHeapOrdered(int);
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/MaxPQ$HeapIterator.class
package edu.princeton.cs.algs4;
synchronized class MaxPQ$HeapIterator implements java.util.Iterator {
private MaxPQ copy;
public void MaxPQ$HeapIterator(MaxPQ);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/MergeBU.class
package edu.princeton.cs.algs4;
public synchronized class MergeBU {
private void MergeBU();
private static void merge(Comparable[], Comparable[], int, int, int);
public static void sort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static boolean isSorted(Comparable[]);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Merge.class
package edu.princeton.cs.algs4;
public synchronized class Merge {
private void Merge();
private static void merge(Comparable[], Comparable[], int, int, int);
private static void sort(Comparable[], Comparable[], int, int);
public static void sort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static void merge(Comparable[], int[], int[], int, int, int);
public static int[] indexSort(Comparable[]);
private static void sort(Comparable[], int[], int[], int, int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/MergeX.class
package edu.princeton.cs.algs4;
public synchronized class MergeX {
private static final int CUTOFF = 7;
private void MergeX();
private static void merge(Comparable[], Comparable[], int, int, int);
private static void sort(Comparable[], Comparable[], int, int);
public static void sort(Comparable[]);
private static void insertionSort(Comparable[], int, int);
private static void exch(Object[], int, int);
private static boolean less(Comparable, Comparable);
private static boolean less(Object, Object, java.util.Comparator);
public static void sort(Object[], java.util.Comparator);
private static void merge(Object[], Object[], int, int, int, java.util.Comparator);
private static void sort(Object[], Object[], int, int, java.util.Comparator);
private static void insertionSort(Object[], int, int, java.util.Comparator);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static boolean isSorted(Object[], java.util.Comparator);
private static boolean isSorted(Object[], int, int, java.util.Comparator);
private static void show(Object[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/MinPQ.class
package edu.princeton.cs.algs4;
public synchronized class MinPQ implements Iterable {
private Object[] pq;
private int n;
private java.util.Comparator comparator;
public void MinPQ(int);
public void MinPQ();
public void MinPQ(int, java.util.Comparator);
public void MinPQ(java.util.Comparator);
public void MinPQ(Object[]);
public boolean isEmpty();
public int size();
public Object min();
private void resize(int);
public void insert(Object);
public Object delMin();
private void swim(int);
private void sink(int);
private boolean greater(int, int);
private void exch(int, int);
private boolean isMinHeap();
private boolean isMinHeapOrdered(int);
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/MinPQ$HeapIterator.class
package edu.princeton.cs.algs4;
synchronized class MinPQ$HeapIterator implements java.util.Iterator {
private MinPQ copy;
public void MinPQ$HeapIterator(MinPQ);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/MSD.class
package edu.princeton.cs.algs4;
public synchronized class MSD {
private static final int BITS_PER_BYTE = 8;
private static final int BITS_PER_INT = 32;
private static final int R = 256;
private static final int CUTOFF = 15;
private void MSD();
public static void sort(String[]);
private static int charAt(String, int);
private static void sort(String[], int, int, int, String[]);
private static void insertion(String[], int, int, int);
private static void exch(String[], int, int);
private static boolean less(String, String, int);
public static void sort(int[]);
private static void sort(int[], int, int, int, int[]);
private static void insertion(int[], int, int, int);
private static void exch(int[], int, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Multiway.class
package edu.princeton.cs.algs4;
public synchronized class Multiway {
private void Multiway();
private static void merge(In[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/MultiwayMinPQ$1.class
package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$1 {
}

edu/princeton/cs/algs4/MultiwayMinPQ.class
package edu.princeton.cs.algs4;
public synchronized class MultiwayMinPQ implements Iterable {
private final int d;
private int n;
private int order;
private Object[] keys;
private final java.util.Comparator comp;
public void MultiwayMinPQ(int);
public void MultiwayMinPQ(java.util.Comparator, int);
public void MultiwayMinPQ(Object[], int);
public void MultiwayMinPQ(java.util.Comparator, Object[], int);
public boolean isEmpty();
public int size();
public void insert(Object);
public Object minKey();
public Object delMin();
private boolean greater(int, int);
private void exch(int, int);
private int getN(int);
private void swim(int);
private void sink(int);
private int minChild(int);
private void resize(int);
public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/MultiwayMinPQ$MyComparator.class
package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$MyComparator implements java.util.Comparator {
private void MultiwayMinPQ$MyComparator(MultiwayMinPQ);
public int compare(Object, Object);
}

edu/princeton/cs/algs4/MultiwayMinPQ$MyIterator.class
package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$MyIterator implements java.util.Iterator {
MultiwayMinPQ data;
public void MultiwayMinPQ$MyIterator(MultiwayMinPQ);
public boolean hasNext();
public Object next();
public void remove();
}

edu/princeton/cs/algs4/NFA.class
package edu.princeton.cs.algs4;
public synchronized class NFA {
private Digraph graph;
private String regexp;
private final int m;
public void NFA(String);
public boolean recognizes(String);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/NonrecursiveDFS.class
package edu.princeton.cs.algs4;
public synchronized class NonrecursiveDFS {
private boolean[] marked;
public void NonrecursiveDFS(Graph, int);
public boolean marked(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/NonrecursiveDirectedDFS.class
package edu.princeton.cs.algs4;
public synchronized class NonrecursiveDirectedDFS {
private boolean[] marked;
public void NonrecursiveDirectedDFS(Digraph, int);
public boolean marked(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Out.class
package edu.princeton.cs.algs4;
public synchronized class Out {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private java.io.PrintWriter out;
public void Out(java.io.OutputStream);
public void Out();
public void Out(java.net.Socket);
public void Out(String);
public void close();
public void println();
public void println(Object);
public void println(boolean);
public void println(char);
public void println(double);
public void println(float);
public void println(int);
public void println(long);
public void println(byte);
public void print();
public void print(Object);
public void print(boolean);
public void print(char);
public void print(double);
public void print(float);
public void print(int);
public void print(long);
public void print(byte);
public transient void printf(String, Object[]);
public transient void printf(java.util.Locale, String, Object[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Particle.class
package edu.princeton.cs.algs4;
public synchronized class Particle {
private static final double INFINITY = Infinity;
private double rx;
private double ry;
private double vx;
private double vy;
private int count;
private final double radius;
private final double mass;
private final java.awt.Color color;
public void Particle(double, double, double, double, double, double, java.awt.Color);
public void Particle();
public void move(double);
public void draw();
public int count();
public double timeToHit(Particle);
public double timeToHitVerticalWall();
public double timeToHitHorizontalWall();
public void bounceOff(Particle);
public void bounceOffVerticalWall();
public void bounceOffHorizontalWall();
public double kineticEnergy();
}

edu/princeton/cs/algs4/PatriciaSET.class
package edu.princeton.cs.algs4;
public synchronized class PatriciaSET implements Iterable {
private PatriciaSET$Node head;
private int count;
public void PatriciaSET();
public void add(String);
public boolean contains(String);
public void delete(String);
boolean isEmpty();
int size();
public java.util.Iterator iterator();
private void collect(PatriciaSET$Node, int, Queue);
public String toString();
private static boolean safeBitTest(String, int);
private static int bitTest(String, int);
private static int safeCharAt(String, int);
private static int firstDifferingBit(String, String);
public static void main(String[]);
}

edu/princeton/cs/algs4/PatriciaSET$Node.class
package edu.princeton.cs.algs4;
synchronized class PatriciaSET$Node {
private PatriciaSET$Node left;
private PatriciaSET$Node right;
private String key;
private int b;
public void PatriciaSET$Node(PatriciaSET, String, int);
}

edu/princeton/cs/algs4/PatriciaST.class
package edu.princeton.cs.algs4;
public synchronized class PatriciaST {
private PatriciaST$Node head;
private int count;
public void PatriciaST();
public void put(String, Object);
public Object get(String);
public void delete(String);
public boolean contains(String);
boolean isEmpty();
int size();
public Iterable keys();
private void keys(PatriciaST$Node, int, Queue);
private static boolean safeBitTest(String, int);
private static int bitTest(String, int);
private static int safeCharAt(String, int);
private static int firstDifferingBit(String, String);
public static void main(String[]);
}

edu/princeton/cs/algs4/PatriciaST$Node.class
package edu.princeton.cs.algs4;
synchronized class PatriciaST$Node {
private PatriciaST$Node left;
private PatriciaST$Node right;
private String key;
private Object val;
private int b;
public void PatriciaST$Node(PatriciaST, String, Object, int);
}

edu/princeton/cs/algs4/Picture.class
package edu.princeton.cs.algs4;
public final synchronized class Picture implements java.awt.event.ActionListener {
private java.awt.image.BufferedImage image;
private javax.swing.JFrame frame;
private String filename;
private boolean isOriginUpperLeft;
private final int width;
private final int height;
public void Picture(int, int);
public void Picture(Picture);
public void Picture(String);
public void Picture(java.io.File);
public javax.swing.JLabel getJLabel();
public void setOriginUpperLeft();
public void setOriginLowerLeft();
public void show();
public int height();
public int width();
private void validateRowIndex(int);
private void validateColumnIndex(int);
public java.awt.Color get(int, int);
public int getRGB(int, int);
public void set(int, int, java.awt.Color);
public void setRGB(int, int, int);
public boolean equals(Object);
public String toString();
public int hashCode();
public void save(String);
public void save(java.io.File);
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
}

edu/princeton/cs/algs4/PictureDump.class
package edu.princeton.cs.algs4;
public synchronized class PictureDump {
private void PictureDump();
public static void main(String[]);
}

edu/princeton/cs/algs4/Point2D$1.class
package edu.princeton.cs.algs4;
synchronized class Point2D$1 {
}

edu/princeton/cs/algs4/Point2D$Atan2Order.class
package edu.princeton.cs.algs4;
synchronized class Point2D$Atan2Order implements java.util.Comparator {
private void Point2D$Atan2Order(Point2D);
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D.class
package edu.princeton.cs.algs4;
public final synchronized class Point2D implements Comparable {
public static final java.util.Comparator X_ORDER;
public static final java.util.Comparator Y_ORDER;
public static final java.util.Comparator R_ORDER;
private final double x;
private final double y;
public void Point2D(double, double);
public double x();
public double y();
public double r();
public double theta();
private double angleTo(Point2D);
public static int ccw(Point2D, Point2D, Point2D);
public static double area2(Point2D, Point2D, Point2D);
public double distanceTo(Point2D);
public double distanceSquaredTo(Point2D);
public int compareTo(Point2D);
public java.util.Comparator polarOrder();
public java.util.Comparator atan2Order();
public java.util.Comparator distanceToOrder();
public boolean equals(Object);
public String toString();
public int hashCode();
public void draw();
public void drawTo(Point2D);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Point2D$DistanceToOrder.class
package edu.princeton.cs.algs4;
synchronized class Point2D$DistanceToOrder implements java.util.Comparator {
private void Point2D$DistanceToOrder(Point2D);
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$PolarOrder.class
package edu.princeton.cs.algs4;
synchronized class Point2D$PolarOrder implements java.util.Comparator {
private void Point2D$PolarOrder(Point2D);
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$ROrder.class
package edu.princeton.cs.algs4;
synchronized class Point2D$ROrder implements java.util.Comparator {
private void Point2D$ROrder();
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$XOrder.class
package edu.princeton.cs.algs4;
synchronized class Point2D$XOrder implements java.util.Comparator {
private void Point2D$XOrder();
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$YOrder.class
package edu.princeton.cs.algs4;
synchronized class Point2D$YOrder implements java.util.Comparator {
private void Point2D$YOrder();
public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Polynomial.class
package edu.princeton.cs.algs4;
public synchronized class Polynomial {
private int[] coef;
private int degree;
public void Polynomial(int, int);
private void reduce();
public int degree();
public Polynomial plus(Polynomial);
public Polynomial minus(Polynomial);
public Polynomial times(Polynomial);
public Polynomial compose(Polynomial);
public boolean equals(Object);
public Polynomial differentiate();
public int evaluate(int);
public int compareTo(Polynomial);
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/PrimMST.class
package edu.princeton.cs.algs4;
public synchronized class PrimMST {
private static final double FLOATING_POINT_EPSILON = 1.0E-12;
private Edge[] edgeTo;
private double[] distTo;
private boolean[] marked;
private IndexMinPQ pq;
public void PrimMST(EdgeWeightedGraph);
private void prim(EdgeWeightedGraph, int);
private void scan(EdgeWeightedGraph, int);
public Iterable edges();
public double weight();
private boolean check(EdgeWeightedGraph);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Queue$1.class
package edu.princeton.cs.algs4;
synchronized class Queue$1 {
}

edu/princeton/cs/algs4/Queue.class
package edu.princeton.cs.algs4;
public synchronized class Queue implements Iterable {
private Queue$Node first;
private Queue$Node last;
private int n;
public void Queue();
public boolean isEmpty();
public int size();
public Object peek();
public void enqueue(Object);
public Object dequeue();
public String toString();
public java.util.Iterator iterator();
public static void main(String[]);
}

edu/princeton/cs/algs4/Queue$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class Queue$ListIterator implements java.util.Iterator {
private Queue$Node current;
public void Queue$ListIterator(Queue, Queue$Node);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/Queue$Node.class
package edu.princeton.cs.algs4;
synchronized class Queue$Node {
private Object item;
private Queue$Node next;
private void Queue$Node();
}

edu/princeton/cs/algs4/Quick3string.class
package edu.princeton.cs.algs4;
public synchronized class Quick3string {
private static final int CUTOFF = 15;
private void Quick3string();
public static void sort(String[]);
private static int charAt(String, int);
private static void sort(String[], int, int, int);
private static void insertion(String[], int, int, int);
private static void exch(String[], int, int);
private static boolean less(String, String, int);
private static boolean isSorted(String[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Quick3way.class
package edu.princeton.cs.algs4;
public synchronized class Quick3way {
private void Quick3way();
public static void sort(Comparable[]);
private static void sort(Comparable[], int, int);
private static boolean less(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/QuickBentleyMcIlroy.class
package edu.princeton.cs.algs4;
public synchronized class QuickBentleyMcIlroy {
private static final int INSERTION_SORT_CUTOFF = 8;
private static final int MEDIAN_OF_3_CUTOFF = 40;
private void QuickBentleyMcIlroy();
public static void sort(Comparable[]);
private static void sort(Comparable[], int, int);
private static void insertionSort(Comparable[], int, int);
private static int median3(Comparable[], int, int, int);
private static boolean less(Comparable, Comparable);
private static boolean eq(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Quick.class
package edu.princeton.cs.algs4;
public synchronized class Quick {
private void Quick();
public static void sort(Comparable[]);
private static void sort(Comparable[], int, int);
private static int partition(Comparable[], int, int);
public static Comparable select(Comparable[], int);
private static boolean less(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/QuickFindUF.class
package edu.princeton.cs.algs4;
public synchronized class QuickFindUF {
private int[] id;
private int count;
public void QuickFindUF(int);
public int count();
public int find(int);
private void validate(int);
public boolean connected(int, int);
public void union(int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/QuickUnionUF.class
package edu.princeton.cs.algs4;
public synchronized class QuickUnionUF {
private int[] parent;
private int count;
public void QuickUnionUF(int);
public int count();
public int find(int);
private void validate(int);
public boolean connected(int, int);
public void union(int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/QuickX.class
package edu.princeton.cs.algs4;
public synchronized class QuickX {
private static final int INSERTION_SORT_CUTOFF = 8;
private void QuickX();
public static void sort(Comparable[]);
private static void sort(Comparable[], int, int);
private static int partition(Comparable[], int, int);
private static int median3(Comparable[], int, int, int);
private static boolean less(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/RabinKarp.class
package edu.princeton.cs.algs4;
public synchronized class RabinKarp {
private String pat;
private long patHash;
private int m;
private long q;
private int R;
private long RM;
public void RabinKarp(char[], int);
public void RabinKarp(String);
private long hash(String, int);
private boolean check(String, int);
public int search(String);
private static long longRandomPrime();
public static void main(String[]);
}

edu/princeton/cs/algs4/RandomSeq.class
package edu.princeton.cs.algs4;
public synchronized class RandomSeq {
private void RandomSeq();
public static void main(String[]);
}

edu/princeton/cs/algs4/RectHV.class
package edu.princeton.cs.algs4;
public final synchronized class RectHV {
private final double xmin;
private final double ymin;
private final double xmax;
private final double ymax;
public void RectHV(double, double, double, double);
public double xmin();
public double xmax();
public double ymin();
public double ymax();
public double width();
public double height();
public boolean intersects(RectHV);
public boolean contains(Point2D);
public double distanceTo(Point2D);
public double distanceSquaredTo(Point2D);
public boolean equals(Object);
public int hashCode();
public String toString();
public void draw();
}

edu/princeton/cs/algs4/RedBlackBST.class
package edu.princeton.cs.algs4;
public synchronized class RedBlackBST {
private static final boolean RED = 1;
private static final boolean BLACK = 0;
private RedBlackBST$Node root;
public void RedBlackBST();
private boolean isRed(RedBlackBST$Node);
private int size(RedBlackBST$Node);
public int size();
public boolean isEmpty();
public Object get(Comparable);
private Object get(RedBlackBST$Node, Comparable);
public boolean contains(Comparable);
public void put(Comparable, Object);
private RedBlackBST$Node put(RedBlackBST$Node, Comparable, Object);
public void deleteMin();
private RedBlackBST$Node deleteMin(RedBlackBST$Node);
public void deleteMax();
private RedBlackBST$Node deleteMax(RedBlackBST$Node);
public void delete(Comparable);
private RedBlackBST$Node delete(RedBlackBST$Node, Comparable);
private RedBlackBST$Node rotateRight(RedBlackBST$Node);
private RedBlackBST$Node rotateLeft(RedBlackBST$Node);
private void flipColors(RedBlackBST$Node);
private RedBlackBST$Node moveRedLeft(RedBlackBST$Node);
private RedBlackBST$Node moveRedRight(RedBlackBST$Node);
private RedBlackBST$Node balance(RedBlackBST$Node);
public int height();
private int height(RedBlackBST$Node);
public Comparable min();
private RedBlackBST$Node min(RedBlackBST$Node);
public Comparable max();
private RedBlackBST$Node max(RedBlackBST$Node);
public Comparable floor(Comparable);
private RedBlackBST$Node floor(RedBlackBST$Node, Comparable);
public Comparable ceiling(Comparable);
private RedBlackBST$Node ceiling(RedBlackBST$Node, Comparable);
public Comparable select(int);
private RedBlackBST$Node select(RedBlackBST$Node, int);
public int rank(Comparable);
private int rank(Comparable, RedBlackBST$Node);
public Iterable keys();
public Iterable keys(Comparable, Comparable);
private void keys(RedBlackBST$Node, Queue, Comparable, Comparable);
public int size(Comparable, Comparable);
private boolean check();
private boolean isBST();
private boolean isBST(RedBlackBST$Node, Comparable, Comparable);
private boolean isSizeConsistent();
private boolean isSizeConsistent(RedBlackBST$Node);
private boolean isRankConsistent();
private boolean is23();
private boolean is23(RedBlackBST$Node);
private boolean isBalanced();
private boolean isBalanced(RedBlackBST$Node, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/RedBlackBST$Node.class
package edu.princeton.cs.algs4;
synchronized class RedBlackBST$Node {
private Comparable key;
private Object val;
private RedBlackBST$Node left;
private RedBlackBST$Node right;
private boolean color;
private int size;
public void RedBlackBST$Node(RedBlackBST, Comparable, Object, boolean, int);
}

edu/princeton/cs/algs4/ResizingArrayBag$1.class
package edu.princeton.cs.algs4;
synchronized class ResizingArrayBag$1 {
}

edu/princeton/cs/algs4/ResizingArrayBag$ArrayIterator.class
package edu.princeton.cs.algs4;
synchronized class ResizingArrayBag$ArrayIterator implements java.util.Iterator {
private int i;
private void ResizingArrayBag$ArrayIterator(ResizingArrayBag);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/ResizingArrayBag.class
package edu.princeton.cs.algs4;
public synchronized class ResizingArrayBag implements Iterable {
private Object[] a;
private int n;
public void ResizingArrayBag();
public boolean isEmpty();
public int size();
private void resize(int);
public void add(Object);
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/ResizingArrayQueue$1.class
package edu.princeton.cs.algs4;
synchronized class ResizingArrayQueue$1 {
}

edu/princeton/cs/algs4/ResizingArrayQueue$ArrayIterator.class
package edu.princeton.cs.algs4;
synchronized class ResizingArrayQueue$ArrayIterator implements java.util.Iterator {
private int i;
private void ResizingArrayQueue$ArrayIterator(ResizingArrayQueue);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/ResizingArrayQueue.class
package edu.princeton.cs.algs4;
public synchronized class ResizingArrayQueue implements Iterable {
private Object[] q;
private int n;
private int first;
private int last;
public void ResizingArrayQueue();
public boolean isEmpty();
public int size();
private void resize(int);
public void enqueue(Object);
public Object dequeue();
public Object peek();
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/ResizingArrayStack.class
package edu.princeton.cs.algs4;
public synchronized class ResizingArrayStack implements Iterable {
private Object[] a;
private int n;
public void ResizingArrayStack();
public boolean isEmpty();
public int size();
private void resize(int);
public void push(Object);
public Object pop();
public Object peek();
public java.util.Iterator iterator();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/ResizingArrayStack$ReverseArrayIterator.class
package edu.princeton.cs.algs4;
synchronized class ResizingArrayStack$ReverseArrayIterator implements java.util.Iterator {
private int i;
public void ResizingArrayStack$ReverseArrayIterator(ResizingArrayStack);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/RunLength.class
package edu.princeton.cs.algs4;
public synchronized class RunLength {
private static final int R = 256;
private static final int LG_R = 8;
private void RunLength();
public static void expand();
public static void compress();
public static void main(String[]);
}

edu/princeton/cs/algs4/SegmentTree.class
package edu.princeton.cs.algs4;
public synchronized class SegmentTree {
private SegmentTree$Node[] heap;
private int[] array;
private int size;
public void SegmentTree(int[]);
public int size();
private void build(int, int, int);
public int rsq(int, int);
private int rsq(int, int, int);
public int rMinQ(int, int);
private int rMinQ(int, int, int);
public void update(int, int, int);
private void update(int, int, int, int);
private void propagate(int);
private void change(SegmentTree$Node, int);
private boolean contains(int, int, int, int);
private boolean intersects(int, int, int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/SegmentTree$Node.class
package edu.princeton.cs.algs4;
synchronized class SegmentTree$Node {
int sum;
int min;
Integer pendingVal;
int from;
int to;
void SegmentTree$Node();
int size();
}

edu/princeton/cs/algs4/Selection.class
package edu.princeton.cs.algs4;
public synchronized class Selection {
private void Selection();
public static void sort(Comparable[]);
public static void sort(Object[], java.util.Comparator);
private static boolean less(Comparable, Comparable);
private static boolean less(java.util.Comparator, Object, Object);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static boolean isSorted(Comparable[], int, int);
private static boolean isSorted(Object[], java.util.Comparator);
private static boolean isSorted(Object[], java.util.Comparator, int, int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/SeparateChainingHashST.class
package edu.princeton.cs.algs4;
public synchronized class SeparateChainingHashST {
private static final int INIT_CAPACITY = 4;
private int n;
private int m;
private SequentialSearchST[] st;
public void SeparateChainingHashST();
public void SeparateChainingHashST(int);
private void resize(int);
private int hash(Object);
public int size();
public boolean isEmpty();
public boolean contains(Object);
public Object get(Object);
public void put(Object, Object);
public void delete(Object);
public Iterable keys();
public static void main(String[]);
}

edu/princeton/cs/algs4/SequentialSearchST.class
package edu.princeton.cs.algs4;
public synchronized class SequentialSearchST {
private int n;
private SequentialSearchST$Node first;
public void SequentialSearchST();
public int size();
public boolean isEmpty();
public boolean contains(Object);
public Object get(Object);
public void put(Object, Object);
public void delete(Object);
private SequentialSearchST$Node delete(SequentialSearchST$Node, Object);
public Iterable keys();
public static void main(String[]);
}

edu/princeton/cs/algs4/SequentialSearchST$Node.class
package edu.princeton.cs.algs4;
synchronized class SequentialSearchST$Node {
private Object key;
private Object val;
private SequentialSearchST$Node next;
public void SequentialSearchST$Node(SequentialSearchST, Object, Object, SequentialSearchST$Node);
}

edu/princeton/cs/algs4/SET.class
package edu.princeton.cs.algs4;
public synchronized class SET implements Iterable {
private java.util.TreeSet set;
public void SET();
public void SET(SET);
public void add(Comparable);
public boolean contains(Comparable);
public void delete(Comparable);
public void remove(Comparable);
public int size();
public boolean isEmpty();
public java.util.Iterator iterator();
public Comparable max();
public Comparable min();
public Comparable ceiling(Comparable);
public Comparable floor(Comparable);
public SET union(SET);
public SET intersects(SET);
public boolean equals(Object);
public int hashCode();
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/Shell.class
package edu.princeton.cs.algs4;
public synchronized class Shell {
private void Shell();
public static void sort(Comparable[]);
private static boolean less(Comparable, Comparable);
private static void exch(Object[], int, int);
private static boolean isSorted(Comparable[]);
private static boolean isHsorted(Comparable[], int);
private static void show(Comparable[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/SparseVector.class
package edu.princeton.cs.algs4;
public synchronized class SparseVector {
private int d;
private ST st;
public void SparseVector(int);
public void put(int, double);
public double get(int);
public int nnz();
public int size();
public int dimension();
public double dot(SparseVector);
public double dot(double[]);
public double magnitude();
public double norm();
public SparseVector scale(double);
public SparseVector plus(SparseVector);
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/Stack$1.class
package edu.princeton.cs.algs4;
synchronized class Stack$1 {
}

edu/princeton/cs/algs4/Stack.class
package edu.princeton.cs.algs4;
public synchronized class Stack implements Iterable {
private Stack$Node first;
private int n;
public void Stack();
public boolean isEmpty();
public int size();
public void push(Object);
public Object pop();
public Object peek();
public String toString();
public java.util.Iterator iterator();
public static void main(String[]);
}

edu/princeton/cs/algs4/Stack$ListIterator.class
package edu.princeton.cs.algs4;
synchronized class Stack$ListIterator implements java.util.Iterator {
private Stack$Node current;
public void Stack$ListIterator(Stack, Stack$Node);
public boolean hasNext();
public void remove();
public Object next();
}

edu/princeton/cs/algs4/Stack$Node.class
package edu.princeton.cs.algs4;
synchronized class Stack$Node {
private Object item;
private Stack$Node next;
private void Stack$Node();
}

edu/princeton/cs/algs4/StaticSETofInts.class
package edu.princeton.cs.algs4;
public synchronized class StaticSETofInts {
private int[] a;
public void StaticSETofInts(int[]);
public boolean contains(int);
public int rank(int);
}

edu/princeton/cs/algs4/ST.class
package edu.princeton.cs.algs4;
public synchronized class ST implements Iterable {
private java.util.TreeMap st;
public void ST();
public Object get(Comparable);
public void put(Comparable, Object);
public void delete(Comparable);
public void remove(Comparable);
public boolean contains(Comparable);
public int size();
public boolean isEmpty();
public Iterable keys();
public java.util.Iterator iterator();
public Comparable min();
public Comparable max();
public Comparable ceiling(Comparable);
public Comparable floor(Comparable);
public static void main(String[]);
}

edu/princeton/cs/algs4/StdArrayIO.class
package edu.princeton.cs.algs4;
public synchronized class StdArrayIO {
private void StdArrayIO();
public static double[] readDouble1D();
public static void print(double[]);
public static double[][] readDouble2D();
public static void print(double[][]);
public static int[] readInt1D();
public static void print(int[]);
public static int[][] readInt2D();
public static void print(int[][]);
public static boolean[] readBoolean1D();
public static void print(boolean[]);
public static boolean[][] readBoolean2D();
public static void print(boolean[][]);
public static void main(String[]);
}

edu/princeton/cs/algs4/StdAudio$1.class
package edu.princeton.cs.algs4;
final synchronized class StdAudio$1 implements Runnable {
void StdAudio$1(String);
public void run();
}

edu/princeton/cs/algs4/StdAudio$2.class
package edu.princeton.cs.algs4;
final synchronized class StdAudio$2 implements Runnable {
void StdAudio$2();
public void run();
}

edu/princeton/cs/algs4/StdAudio.class
package edu.princeton.cs.algs4;
public final synchronized class StdAudio {
public static final int SAMPLE_RATE = 44100;
private static final int BYTES_PER_SAMPLE = 2;
private static final int BITS_PER_SAMPLE = 16;
private static final double MAX_16_BIT = 32768.0;
private static final int SAMPLE_BUFFER_SIZE = 4096;
private static final int MONO = 1;
private static final int STEREO = 2;
private static final boolean LITTLE_ENDIAN = 0;
private static final boolean BIG_ENDIAN = 1;
private static final boolean SIGNED = 1;
private static final boolean UNSIGNED = 0;
private static javax.sound.sampled.SourceDataLine line;
private static byte[] buffer;
private static int bufferSize;
private void StdAudio();
private static void init();
private static javax.sound.sampled.AudioInputStream getAudioInputStreamFromFile(String);
public static void close();
public static void play(double);
public static void play(double[]);
public static double[] read(String);
public static void save(String, double[]);
public static synchronized void play(String);
private static void stream(javax.sound.sampled.AudioInputStream);
public static synchronized void loop(String);
private static double[] note(double, double, double);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/StdDraw.class
package edu.princeton.cs.algs4;
public final synchronized class StdDraw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
public static final java.awt.Color BLACK;
public static final java.awt.Color BLUE;
public static final java.awt.Color CYAN;
public static final java.awt.Color DARK_GRAY;
public static final java.awt.Color GRAY;
public static final java.awt.Color GREEN;
public static final java.awt.Color LIGHT_GRAY;
public static final java.awt.Color MAGENTA;
public static final java.awt.Color ORANGE;
public static final java.awt.Color PINK;
public static final java.awt.Color RED;
public static final java.awt.Color WHITE;
public static final java.awt.Color YELLOW;
public static final java.awt.Color BOOK_BLUE;
public static final java.awt.Color BOOK_LIGHT_BLUE;
public static final java.awt.Color BOOK_RED;
public static final java.awt.Color PRINCETON_ORANGE;
private static final java.awt.Color DEFAULT_PEN_COLOR;
private static final java.awt.Color DEFAULT_CLEAR_COLOR;
private static java.awt.Color penColor;
private static final int DEFAULT_SIZE = 512;
private static int width;
private static int height;
private static final double DEFAULT_PEN_RADIUS = 0.002;
private static double penRadius;
private static boolean defer;
private static final double BORDER = 0.0;
private static final double DEFAULT_XMIN = 0.0;
private static final double DEFAULT_XMAX = 1.0;
private static final double DEFAULT_YMIN = 0.0;
private static final double DEFAULT_YMAX = 1.0;
private static double xmin;
private static double ymin;
private static double xmax;
private static double ymax;
private static Object mouseLock;
private static Object keyLock;
private static final java.awt.Font DEFAULT_FONT;
private static java.awt.Font font;
private static java.awt.image.BufferedImage offscreenImage;
private static java.awt.image.BufferedImage onscreenImage;
private static java.awt.Graphics2D offscreen;
private static java.awt.Graphics2D onscreen;
private static StdDraw std;
private static javax.swing.JFrame frame;
private static boolean isMousePressed;
private static double mouseX;
private static double mouseY;
private static java.util.LinkedList keysTyped;
private static java.util.TreeSet keysDown;
private void StdDraw();
public static void setCanvasSize();
public static void setCanvasSize(int, int);
private static void init();
private static javax.swing.JMenuBar createMenuBar();
private static void validate(double, String);
private static void validateNonnegative(double, String);
private static void validateNotNull(Object, String);
public static void setXscale();
public static void setYscale();
public static void setScale();
public static void setXscale(double, double);
public static void setYscale(double, double);
public static void setScale(double, double);
private static double scaleX(double);
private static double scaleY(double);
private static double factorX(double);
private static double factorY(double);
private static double userX(double);
private static double userY(double);
public static void clear();
public static void clear(java.awt.Color);
public static double getPenRadius();
public static void setPenRadius();
public static void setPenRadius(double);
public static java.awt.Color getPenColor();
public static void setPenColor();
public static void setPenColor(java.awt.Color);
public static void setPenColor(int, int, int);
public static java.awt.Font getFont();
public static void setFont();
public static void setFont(java.awt.Font);
public static void line(double, double, double, double);
private static void pixel(double, double);
public static void point(double, double);
public static void circle(double, double, double);
public static void filledCircle(double, double, double);
public static void ellipse(double, double, double, double);
public static void filledEllipse(double, double, double, double);
public static void arc(double, double, double, double, double);
public static void square(double, double, double);
public static void filledSquare(double, double, double);
public static void rectangle(double, double, double, double);
public static void filledRectangle(double, double, double, double);
public static void polygon(double[], double[]);
public static void filledPolygon(double[], double[]);
private static java.awt.Image getImage(String);
public static void picture(double, double, String);
public static void picture(double, double, String, double);
public static void picture(double, double, String, double, double);
public static void picture(double, double, String, double, double, double);
public static void text(double, double, String);
public static void text(double, double, String, double);
public static void textLeft(double, double, String);
public static void textRight(double, double, String);
public static void show(int);
public static void pause(int);
public static void show();
private static void draw();
public static void enableDoubleBuffering();
public static void disableDoubleBuffering();
public static void save(String);
public void actionPerformed(java.awt.event.ActionEvent);
public static boolean isMousePressed();
public static boolean mousePressed();
public static double mouseX();
public static double mouseY();
public void mouseClicked(java.awt.event.MouseEvent);
public void mouseEntered(java.awt.event.MouseEvent);
public void mouseExited(java.awt.event.MouseEvent);
public void mousePressed(java.awt.event.MouseEvent);
public void mouseReleased(java.awt.event.MouseEvent);
public void mouseDragged(java.awt.event.MouseEvent);
public void mouseMoved(java.awt.event.MouseEvent);
public static boolean hasNextKeyTyped();
public static char nextKeyTyped();
public static boolean isKeyPressed(int);
public void keyTyped(java.awt.event.KeyEvent);
public void keyPressed(java.awt.event.KeyEvent);
public void keyReleased(java.awt.event.KeyEvent);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/StdDraw$RetinaImageIcon.class
package edu.princeton.cs.algs4;
synchronized class StdDraw$RetinaImageIcon extends javax.swing.ImageIcon {
public void StdDraw$RetinaImageIcon(java.awt.Image);
public int getIconWidth();
public int getIconHeight();
public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

edu/princeton/cs/algs4/StdIn.class
package edu.princeton.cs.algs4;
public final synchronized class StdIn {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static final java.util.regex.Pattern WHITESPACE_PATTERN;
private static final java.util.regex.Pattern EMPTY_PATTERN;
private static final java.util.regex.Pattern EVERYTHING_PATTERN;
private static java.util.Scanner scanner;
private void StdIn();
public static boolean isEmpty();
public static boolean hasNextLine();
public static boolean hasNextChar();
public static String readLine();
public static char readChar();
public static String readAll();
public static String readString();
public static int readInt();
public static double readDouble();
public static float readFloat();
public static long readLong();
public static short readShort();
public static byte readByte();
public static boolean readBoolean();
public static String[] readAllStrings();
public static String[] readAllLines();
public static int[] readAllInts();
public static long[] readAllLongs();
public static double[] readAllDoubles();
private static void resync();
private static void setScanner(java.util.Scanner);
public static int[] readInts();
public static double[] readDoubles();
public static String[] readStrings();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/StdOut.class
package edu.princeton.cs.algs4;
public final synchronized class StdOut {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static java.io.PrintWriter out;
private void StdOut();
public static void println();
public static void println(Object);
public static void println(boolean);
public static void println(char);
public static void println(double);
public static void println(float);
public static void println(int);
public static void println(long);
public static void println(short);
public static void println(byte);
public static void print();
public static void print(Object);
public static void print(boolean);
public static void print(char);
public static void print(double);
public static void print(float);
public static void print(int);
public static void print(long);
public static void print(short);
public static void print(byte);
public static transient void printf(String, Object[]);
public static transient void printf(java.util.Locale, String, Object[]);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/StdRandom.class
package edu.princeton.cs.algs4;
public final synchronized class StdRandom {
private static java.util.Random random;
private static long seed;
private void StdRandom();
public static void setSeed(long);
public static long getSeed();
public static double uniform();
public static int uniform(int);
public static long uniform(long);
public static double random();
public static int uniform(int, int);
public static double uniform(double, double);
public static boolean bernoulli(double);
public static boolean bernoulli();
public static double gaussian();
public static double gaussian(double, double);
public static int geometric(double);
public static int poisson(double);
public static double pareto();
public static double pareto(double);
public static double cauchy();
public static int discrete(double[]);
public static int discrete(int[]);
public static double exp(double);
public static void shuffle(Object[]);
public static void shuffle(double[]);
public static void shuffle(int[]);
public static void shuffle(char[]);
public static void shuffle(Object[], int, int);
public static void shuffle(double[], int, int);
public static void shuffle(int[], int, int);
public static int[] permutation(int);
public static int[] permutation(int, int);
private static void validateNotNull(Object);
private static void validateSubarrayIndices(int, int, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/StdStats.class
package edu.princeton.cs.algs4;
public final synchronized class StdStats {
private void StdStats();
public static double max(double[]);
public static double max(double[], int, int);
public static int max(int[]);
public static double min(double[]);
public static double min(double[], int, int);
public static int min(int[]);
public static double mean(double[]);
public static double mean(double[], int, int);
public static double mean(int[]);
public static double var(double[]);
public static double var(double[], int, int);
public static double var(int[]);
public static double varp(double[]);
public static double varp(double[], int, int);
public static double stddev(double[]);
public static double stddev(int[]);
public static double stddev(double[], int, int);
public static double stddevp(double[]);
public static double stddevp(double[], int, int);
private static double sum(double[]);
private static double sum(double[], int, int);
private static int sum(int[]);
public static void plotPoints(double[]);
public static void plotLines(double[]);
public static void plotBars(double[]);
private static void validateNotNull(Object);
private static void validateSubarrayIndices(int, int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Stopwatch.class
package edu.princeton.cs.algs4;
public synchronized class Stopwatch {
private final long start;
public void Stopwatch();
public double elapsedTime();
public static void main(String[]);
}

edu/princeton/cs/algs4/StopwatchCPU.class
package edu.princeton.cs.algs4;
public synchronized class StopwatchCPU {
private static final double NANOSECONDS_PER_SECOND = 1.0E9;
private final management.ThreadMXBean threadTimer;
private final long start;
public void StopwatchCPU();
public double elapsedTime();
public static void main(String[]);
}

edu/princeton/cs/algs4/SuffixArray$1.class
package edu.princeton.cs.algs4;
synchronized class SuffixArray$1 {
}

edu/princeton/cs/algs4/SuffixArray.class
package edu.princeton.cs.algs4;
public synchronized class SuffixArray {
private SuffixArray$Suffix[] suffixes;
public void SuffixArray(String);
public int length();
public int index(int);
public int lcp(int);
private static int lcpSuffix(SuffixArray$Suffix, SuffixArray$Suffix);
public String select(int);
public int rank(String);
private static int compare(String, SuffixArray$Suffix);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/SuffixArray$Suffix.class
package edu.princeton.cs.algs4;
synchronized class SuffixArray$Suffix implements Comparable {
private final String text;
private final int index;
private void SuffixArray$Suffix(String, int);
private int length();
private char charAt(int);
public int compareTo(SuffixArray$Suffix);
public String toString();
}

edu/princeton/cs/algs4/SuffixArrayX.class
package edu.princeton.cs.algs4;
public synchronized class SuffixArrayX {
private static final int CUTOFF = 5;
private final char[] text;
private final int[] index;
private final int n;
public void SuffixArrayX(String);
private void sort(int, int, int);
private void insertion(int, int, int);
private boolean less(int, int, int);
private void exch(int, int);
public int length();
public int index(int);
public int lcp(int);
private int lcp(int, int);
public String select(int);
public int rank(String);
private int compare(String, int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/SymbolDigraph.class
package edu.princeton.cs.algs4;
public synchronized class SymbolDigraph {
private ST st;
private String[] keys;
private Digraph graph;
public void SymbolDigraph(String, String);
public boolean contains(String);
public int index(String);
public int indexOf(String);
public String name(int);
public String nameOf(int);
public Digraph G();
public Digraph digraph();
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/SymbolGraph.class
package edu.princeton.cs.algs4;
public synchronized class SymbolGraph {
private ST st;
private String[] keys;
private Graph graph;
public void SymbolGraph(String, String);
public boolean contains(String);
public int index(String);
public int indexOf(String);
public String name(int);
public String nameOf(int);
public Graph G();
public Graph graph();
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/TarjanSCC.class
package edu.princeton.cs.algs4;
public synchronized class TarjanSCC {
private boolean[] marked;
private int[] id;
private int[] low;
private int pre;
private int count;
private Stack stack;
public void TarjanSCC(Digraph);
private void dfs(Digraph, int);
public int count();
public boolean stronglyConnected(int, int);
public int id(int);
private boolean check(Digraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/ThreeSum.class
package edu.princeton.cs.algs4;
public synchronized class ThreeSum {
private void ThreeSum();
public static void printAll(int[]);
public static int count(int[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/ThreeSumFast.class
package edu.princeton.cs.algs4;
public synchronized class ThreeSumFast {
private void ThreeSumFast();
private static boolean containsDuplicates(int[]);
public static void printAll(int[]);
public static int count(int[]);
public static void main(String[]);
}

edu/princeton/cs/algs4/TopM.class
package edu.princeton.cs.algs4;
public synchronized class TopM {
private void TopM();
public static void main(String[]);
}

edu/princeton/cs/algs4/Topological.class
package edu.princeton.cs.algs4;
public synchronized class Topological {
private Iterable order;
private int[] rank;
public void Topological(Digraph);
public void Topological(EdgeWeightedDigraph);
public Iterable order();
public boolean hasOrder();
public boolean isDAG();
public int rank(int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/TopologicalX.class
package edu.princeton.cs.algs4;
public synchronized class TopologicalX {
private Queue order;
private int[] ranks;
public void TopologicalX(Digraph);
public void TopologicalX(EdgeWeightedDigraph);
public Iterable order();
public boolean hasOrder();
public int rank(int);
private boolean check(Digraph);
private boolean check(EdgeWeightedDigraph);
private void validateVertex(int);
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/Transaction.class
package edu.princeton.cs.algs4;
public synchronized class Transaction implements Comparable {
private final String who;
private final Date when;
private final double amount;
public void Transaction(String, Date, double);
public void Transaction(String);
public String who();
public Date when();
public double amount();
public String toString();
public int compareTo(Transaction);
public boolean equals(Object);
public int hashCode();
public static void main(String[]);
}

edu/princeton/cs/algs4/Transaction$HowMuchOrder.class
package edu.princeton.cs.algs4;
public synchronized class Transaction$HowMuchOrder implements java.util.Comparator {
public void Transaction$HowMuchOrder();
public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/Transaction$WhenOrder.class
package edu.princeton.cs.algs4;
public synchronized class Transaction$WhenOrder implements java.util.Comparator {
public void Transaction$WhenOrder();
public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/Transaction$WhoOrder.class
package edu.princeton.cs.algs4;
public synchronized class Transaction$WhoOrder implements java.util.Comparator {
public void Transaction$WhoOrder();
public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/TransitiveClosure.class
package edu.princeton.cs.algs4;
public synchronized class TransitiveClosure {
private DirectedDFS[] tc;
public void TransitiveClosure(Digraph);
public boolean reachable(int, int);
private void validateVertex(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/TrieSET$1.class
package edu.princeton.cs.algs4;
synchronized class TrieSET$1 {
}

edu/princeton/cs/algs4/TrieSET.class
package edu.princeton.cs.algs4;
public synchronized class TrieSET implements Iterable {
private static final int R = 256;
private TrieSET$Node root;
private int n;
public void TrieSET();
public boolean contains(String);
private TrieSET$Node get(TrieSET$Node, String, int);
public void add(String);
private TrieSET$Node add(TrieSET$Node, String, int);
public int size();
public boolean isEmpty();
public java.util.Iterator iterator();
public Iterable keysWithPrefix(String);
private void collect(TrieSET$Node, StringBuilder, Queue);
public Iterable keysThatMatch(String);
private void collect(TrieSET$Node, StringBuilder, String, Queue);
public String longestPrefixOf(String);
private int longestPrefixOf(TrieSET$Node, String, int, int);
public void delete(String);
private TrieSET$Node delete(TrieSET$Node, String, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/TrieSET$Node.class
package edu.princeton.cs.algs4;
synchronized class TrieSET$Node {
private TrieSET$Node[] next;
private boolean isString;
private void TrieSET$Node();
}

edu/princeton/cs/algs4/TrieST$1.class
package edu.princeton.cs.algs4;
synchronized class TrieST$1 {
}

edu/princeton/cs/algs4/TrieST.class
package edu.princeton.cs.algs4;
public synchronized class TrieST {
private static final int R = 256;
private TrieST$Node root;
private int n;
public void TrieST();
public Object get(String);
public boolean contains(String);
private TrieST$Node get(TrieST$Node, String, int);
public void put(String, Object);
private TrieST$Node put(TrieST$Node, String, Object, int);
public int size();
public boolean isEmpty();
public Iterable keys();
public Iterable keysWithPrefix(String);
private void collect(TrieST$Node, StringBuilder, Queue);
public Iterable keysThatMatch(String);
private void collect(TrieST$Node, StringBuilder, String, Queue);
public String longestPrefixOf(String);
private int longestPrefixOf(TrieST$Node, String, int, int);
public void delete(String);
private TrieST$Node delete(TrieST$Node, String, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/TrieST$Node.class
package edu.princeton.cs.algs4;
synchronized class TrieST$Node {
private Object val;
private TrieST$Node[] next;
private void TrieST$Node();
}

edu/princeton/cs/algs4/TST$1.class
package edu.princeton.cs.algs4;
synchronized class TST$1 {
}

edu/princeton/cs/algs4/TST.class
package edu.princeton.cs.algs4;
public synchronized class TST {
private int n;
private TST$Node root;
public void TST();
public int size();
public boolean contains(String);
public Object get(String);
private TST$Node get(TST$Node, String, int);
public void put(String, Object);
private TST$Node put(TST$Node, String, Object, int);
public String longestPrefixOf(String);
public Iterable keys();
public Iterable keysWithPrefix(String);
private void collect(TST$Node, StringBuilder, Queue);
public Iterable keysThatMatch(String);
private void collect(TST$Node, StringBuilder, int, String, Queue);
public static void main(String[]);
}

edu/princeton/cs/algs4/TST$Node.class
package edu.princeton.cs.algs4;
synchronized class TST$Node {
private char c;
private TST$Node left;
private TST$Node mid;
private TST$Node right;
private Object val;
private void TST$Node();
}

edu/princeton/cs/algs4/TwoPersonZeroSumGame.class
package edu.princeton.cs.algs4;
public synchronized class TwoPersonZeroSumGame {
private static final double EPSILON = 1.0E-8;
private final int m;
private final int n;
private LinearProgramming lp;
private double constant;
public void TwoPersonZeroSumGame(double[][]);
public double value();
private double scale();
public double[] row();
public double[] column();
private boolean isPrimalFeasible();
private boolean isDualFeasible();
private boolean isNashEquilibrium(double[][]);
private boolean certifySolution(double[][]);
private static void test(String, double[][]);
private static void test1();
private static void test2();
private static void test3();
private static void test4();
private static void test5();
public static void main(String[]);
static void ();
}

edu/princeton/cs/algs4/UF.class
package edu.princeton.cs.algs4;
public synchronized class UF {
private int[] parent;
private byte[] rank;
private int count;
public void UF(int);
public int find(int);
public int count();
public boolean connected(int, int);
public void union(int, int);
private void validate(int);
public static void main(String[]);
}

edu/princeton/cs/algs4/Vector.class
package edu.princeton.cs.algs4;
public synchronized class Vector {
private int d;
private double[] data;
public void Vector(int);
public transient void Vector(double[]);
public int length();
public int dimension();
public double dot(Vector);
public double magnitude();
public double distanceTo(Vector);
public Vector plus(Vector);
public Vector minus(Vector);
public double cartesian(int);
public Vector times(double);
public Vector scale(double);
public Vector direction();
public String toString();
public static void main(String[]);
}

edu/princeton/cs/algs4/WeightedQuickUnionUF.class
package edu.princeton.cs.algs4;
public synchronized class WeightedQuickUnionUF {
private int[] parent;
private int[] size;
private int count;
public void WeightedQuickUnionUF(int);
public int count();
public int find(int);
public boolean connected(int, int);
private void validate(int);
public void union(int, int);
public static void main(String[]);
}

edu/princeton/cs/algs4/WhiteFilter.class
package edu.princeton.cs.algs4;
public synchronized class WhiteFilter {
private void WhiteFilter();
public static void main(String[]);
}

edu/princeton/cs/algs4/Whitelist.class
package edu.princeton.cs.algs4;
public synchronized class Whitelist {
private void Whitelist();
public static void main(String[]);
}

TestAlgs4.java
TestAlgs4.java
/******************************************************************************

 *  Compilation:  javac-algs4 TestAlgs4.java

 *  Execution:    java-algs4 TestAlgs4 n

 *  

 *  Simulates the motion of n hard disks, subject to the laws of elastic

 *  collisions. This program is intended to test that algs4.jar is properly

 *  installed.

 * 

 ******************************************************************************/

import
 edu
.
princeton
.
cs
.
algs4
.
CollisionSystem
;

import
 edu
.
princeton
.
cs
.
algs4
.
Particle
;

import
 edu
.
princeton
.
cs
.
algs4
.
StdDraw
;

public
 
class
 
TestAlgs4
 
{

    public static void main(String[] args) {

        int n = 20;  // number of particles (default 20)        if (args.length == 1) {

            n = Integer.parseInt(args[0]);

        }

        // enable double buffering to support animations        StdDraw.enableDoubleBuffering();

        // create the n particles        Particle[] particles = new Particle[n];

        for (int i = 0; i < n; i++) {             particles[i] = new Particle();         }         // simulate the system        CollisionSystem system = new CollisionSystem(particles);         system.simulate(Double.POSITIVE_INFINITY);     } } TestAlgs4.class public synchronized class TestAlgs4 { public void TestAlgs4(); public static void main(String[]); } META-INF/MANIFEST.MF Manifest-Version: 1.0 Created-By: 1.8.0_191 (Oracle Corporation) BinaryIn.java BinaryIn.java /******************************************************************************  *  Compilation:  javac BinaryIn.java  *  Execution:    java BinaryIn input output  *  Dependencies: none               *    *  This library is for reading binary data from an input stream.  *  *  % java BinaryIn https://introcs.cs.princeton.edu/java/cover  output  *  ******************************************************************************/ import  java . io . BufferedInputStream ; import  java . io . File ; import  java . io . FileInputStream ; import  java . io . IOException ; import  java . io . InputStream ; import  java . net . Socket ; import  java . net . URL ; import  java . net . URLConnection ; import  java . util . NoSuchElementException ; /**  *  Binary input. This class provides methods for reading

 *  in bits from a binary input stream, either

 *  one bit at a time (as a {
@code
 boolean}),

 *  8 bits at a time (as a {
@code
 byte} or {
@code
 char}),

 *  16 bits at a time (as a {
@code
 short}),

 *  32 bits at a time (as an {
@code
 int} or {
@code
 float}), or

 *  64 bits at a time (as a {
@code
 double} or {
@code
 long}).

 *  

 *  The binary input stream can be from standard input, a filename,

 *  a URL name, a Socket, or an InputStream.

 *  

 *  All primitive types are assumed to be represented using their 

 *  standard Java representations, in big-endian (most significant

 *  byte first) order.

 *  

 *  The client should not intermix calls to {
@code
 BinaryIn} with calls

 *  to {
@code
 In}; otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryIn
 
{

    
private
 
static
 
final
 
int
 EOF 
=
 

1
;
   
// end of file

    
private
 
BufferedInputStream
 in
;
      
// the input stream

    
private
 
int
 buffer
;
                  
// one character buffer

    
private
 
int
 n
;
                       
// number of bits left in buffer

   
/**

     * Initializes a binary input stream from standard input.

     */

    
public
 
BinaryIn
()
 
{

        in 
=
 
new
 
BufferedInputStream
(
System
.
in
);

        fillBuffer
();

    
}

   
/**

     * Initializes a binary input stream from an {
@code
 InputStream}.

     *

     * 
@param
 is the {
@code
 InputStream} object

     */

    
public
 
BinaryIn
(
InputStream
 is
)
 
{

        in 
=
 
new
 
BufferedInputStream
(
is
);

        fillBuffer
();

    
}

   
/**

     * Initializes a binary input stream from a socket.

     *

     * 
@param
 socket the socket

     */

    
public
 
BinaryIn
(
Socket
 socket
)
 
{

        
try
 
{

            
InputStream
 is 
=
 socket
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 socket
);

        
}

    
}

   
/**

     * Initializes a binary input stream from a URL.

     *

     * 
@param
 url the URL

     */

    
public
 
BinaryIn
(
URL url
)
 
{

        
try
 
{

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 url
);

        
}

    
}

   
/**

     * Initializes a binary input stream from a filename or URL name.

     *

     * 
@param
 name the name of the file or URL

     */

    
public
 
BinaryIn
(
String
 name
)
 
{

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
name
);

            
if
 
(
file
.
exists
())
 
{

                
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

                in 
=
 
new
 
BufferedInputStream
(
fis
);

                fillBuffer
();

                
return
;

            
}

            
// next try for files included in jar

            URL url 
=
 getClass
().
getResource
(
name
);

            
// or URL from web

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 
new
 URL
(
name
);

            
}

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            in 
=
 
new
 
BufferedInputStream
(
is
);

            fillBuffer
();

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
System
.
err
.
println
(
“Could not open ”
 
+
 name
);

        
}

    
}

    
private
 
void
 fillBuffer
()
 
{

        
try
 
{

            buffer 
=
 in
.
read
();

            n 
=
 
8
;

        
}

        
catch
 
(
IOException
 e
)
 
{

            
System
.
err
.
println
(
“EOF”
);

            buffer 
=
 EOF
;

            n 
=
 

1
;

        
}

    
}

    
/**

     * Returns true if this binary input stream exists.

     *

     * 
@return
 {
@code
 true} if this binary input stream exists;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 exists
()
  
{

        
return
 in 
!=
 
null
;

    
}

   
/**

     * Returns true if this binary input stream is empty.

     *

     * 
@return
 {
@code
 true} if this binary input stream is empty;

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 buffer 
==
 EOF
;

    
}

   
/**

     * Reads the next bit of data from this binary input stream and return as a boolean.

     *

     * 
@return
 the next bit of data from this binary input stream as a {
@code
 boolean}

     * 
@throws
 NoSuchElementException if this binary input stream is empty

     */

    
public
 
boolean
 readBoolean
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        n

;

        
boolean
 bit 
=
 
((
buffer 
>>
 n
)
 
&
 
1
)
 
==
 
1
;

        
if
 
(

==
 
0
)
 fillBuffer
();

        
return
 bit
;

    
}

   
/**

     * Reads the next 8 bits from this binary input stream and return as an 8-bit char.

     *

     * 
@return
 the next 8 bits of data from this binary input stream as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than 8 bits available

     */

    
public
 
char
 readChar
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        
// special case when aligned byte

        
if
 
(

==
 
8
)
 
{

            
int
 x 
=
 buffer
;

            fillBuffer
();

            
return
 
(
char
)
 
(

&
 
0xff
);

        
}

        
// combine last N bits of current buffer with first 8-N bits of new buffer

        
int
 x 
=
 buffer
;

        x 
<<=   ( 8   -  n );          int  oldN  =  n ;         fillBuffer ();          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );         n  =  oldN ;         x  |=   ( buffer  >>>
 n
);

        
return
 
(
char
)
 
(

&
 
0xff
);

        
// the above code doesn’t quite work for the last character if N = 8

        
// because buffer will be -1

    
}

   
/**

     * Reads the next r bits from this binary input stream and return as an r-bit character.

     *

     * 
@param
  r number of bits to read

     * 
@return
 the next {
@code
 r} bits of data from this binary input streamt as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than {
@code
 r} bits available

     * 
@throws
 IllegalArgumentException unless {
@code
 1 <= r <= 16}      */      public   char  readChar ( int  r )   {          if   ( r  <   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 8 case

        
if
 
(

==
 
8
)
 
return
 readChar
();

        
char
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the remaining bytes of data from this binary input stream and return as a string.       *      *  @return  the remaining bytes of data from this binary input stream as a { @code  String}      *  @throws  NoSuchElementException if this binary input stream is empty or if the number of bits      *         available is not a multiple of 8 (byte-aligned)      */      public   String  readString ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );          StringBuilder  sb  =   new   StringBuilder ();          while   ( ! isEmpty ())   {              char  c  =  readChar ();             sb . append ( c );          }          return  sb . toString ();      }     /**      * Reads the next 16 bits from this binary input stream and return as a 16-bit short.      *      *  @return  the next 16 bits of data from this binary input stream as a { @code  short}      *  @throws  NoSuchElementException if there are fewer than 16 bits available      */      public   short  readShort ()   {          short  x  =   0 ;          for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 32 bits from this binary input stream and return as a 32-bit int.      *      *  @return  the next 32 bits of data from this binary input stream as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than 32 bits available      */      public   int  readInt ()   {          int  x  =   0 ;          for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next r bits from this binary input stream return as an r-bit int.      *      *  @param   r number of bits to read      *  @return  the next { @code  r} bits of data from this binary input stream as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than r bits available      *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}      */      public   int  readInt ( int  r )   {          if   ( r  <   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 32 case

        
if
 
(

==
 
32
)
 
return
 readInt
();

        
int
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the next 64 bits from this binary input stream and return as a 64-bit long.      *      *  @return  the next 64 bits of data from this binary input stream as a { @code  long}      *  @throws  NoSuchElementException if there are fewer than 64 bits available      */      public   long  readLong ()   {          long  x  =   0 ;          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 64 bits from this binary input stream and return as a 64-bit double.      *      *  @return  the next 64 bits of data from this binary input stream as a { @code  double}      *  @throws  NoSuchElementException if there are fewer than 64 bits available      */      public   double  readDouble ()   {          return   Double . longBitsToDouble ( readLong ());      }     /**      * Reads the next 32 bits from this binary input stream and return as a 32-bit float.      *      *  @return  the next 32 bits of data from this binary input stream as a { @code  float}      *  @throws  NoSuchElementException if there are fewer than 32 bits available      */      public   float  readFloat ()   {          return   Float . intBitsToFloat ( readInt ());      }     /**      * Reads the next 8 bits from this binary input stream and return as an 8-bit byte.      *      *  @return  the next 8 bits of data from this binary input stream as a { @code  byte}      *  @throws  NoSuchElementException if there are fewer than 8 bits available      */      public   byte  readByte ()   {          char  c  =  readChar ();          return   ( byte )   ( c  &   0xff );      }          /**      * Unit tests the { @code  BinaryIn} data type.      * Reads the name of a file or URL (first command-line argument)      * and writes it to a file (second command-line argument).      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          BinaryIn   in   =   new   BinaryIn ( args [ 0 ]);          BinaryOut  out  =   new   BinaryOut ( args [ 1 ]);          // read one 8-bit char at a time          while   ( ! in . isEmpty ())   {              char  c  =  in . readChar ();             out . write ( c );          }         out . flush ();      } } BinaryOut.java BinaryOut.java /******************************************************************************  *  Compilation:  javac BinaryOut.java  *  Execution:    java BinaryOut  *  Dependencies: none  *  *  Write binary data to an output stream, either one 1-bit boolean,  *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,  *  or one 64-bit long at a time. The output stream can be standard  *  output, a file, an OutputStream or a Socket.  *  *  The bytes written are not aligned.  *  ******************************************************************************/ import  java . io . BufferedOutputStream ; import  java . io . FileOutputStream ; import  java . io . IOException ; import  java . io . OutputStream ; import  java . net . Socket ; /**  *  Binary output. This class provides methods for converting

 *  primtive type variables ({
@code
 boolean}, {
@code
 byte}, {
@code
 char},

 *  {
@code
 int}, {
@code
 long}, {
@code
 float}, and {
@code
 double})

 *  to sequences of bits and writing them to an output stream.

 *  The output stream can be standard output, a file, an OutputStream or a Socket.

 *  Uses big-endian (most-significant byte first).

 *  

 *  The client must {
@code
 flush()} the output stream when finished writing bits.

 *  

 *  The client should not intermix calls to {
@code
 BinaryOut} with calls

 *  to {
@code
 Out}; otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryOut
 
{

    
private
 
BufferedOutputStream
 out
;
  
// the output stream

    
private
 
int
 buffer
;
                
// 8-bit buffer of bits to write out

    
private
 
int
 n
;
                     
// number of bits remaining in buffer

   
/**

     * Initializes a binary output stream from standard output.

     */

    
public
 
BinaryOut
()
 
{

        out 
=
 
new
 
BufferedOutputStream
(
System
.
out
);

    
}

   
/**

     * Initializes a binary output stream from an {
@code
 OutputStream}.

     * 
@param
 os the {
@code
 OutputStream}

     */

    
public
 
BinaryOut
(
OutputStream
 os
)
 
{

        out 
=
 
new
 
BufferedOutputStream
(
os
);

    
}

   
/**

     * Initializes a binary output stream from a file.

     * 
@param
 filename the name of the file

     */

    
public
 
BinaryOut
(
String
 filename
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 
new
 
FileOutputStream
(
filename
);

            out 
=
 
new
 
BufferedOutputStream
(
os
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes a binary output stream from a socket.

     * 
@param
 socket the socket

     */

    
public
 
BinaryOut
(
Socket
 socket
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 socket
.
getOutputStream
();

            out 
=
 
new
 
BufferedOutputStream
(
os
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Writes the specified bit to the binary output stream.

     * 
@param
 x the bit

     */

    
private
 
void
 writeBit
(
boolean
 x
)
 
{

        
// add bit to buffer

        buffer 
<<=   1 ;          if   ( x )  buffer  |=   1 ;          // if buffer is full (8 bits), write out as a single byte         n ++ ;          if   ( n  ==   8 )  clearBuffer ();      }       /**      * Writes the 8-bit byte to the binary output stream.      *  @param  x the byte      */      private   void  writeByte ( int  x )   {          assert  x  >=
 
0
 
&&
 x 
<   256 ;          // optimized if byte-aligned          if   ( n  ==   0 )   {              try   {                 out . write ( x );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }              return ;          }          // otherwise write one bit at a time          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(
8
 

 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

    
// write out any remaining bits in buffer to the binary output stream, padding with 0s

    
private
 
void
 clearBuffer
()
 
{

        
if
 
(

==
 
0
)
 
return
;

        
if
 
(

>
 
0
)
 buffer 
<<=   ( 8   -  n );          try   {             out . write ( buffer );          }          catch   ( IOException  e )   {             e . printStackTrace ();          }         n  =   0 ;         buffer  =   0 ;      }     /**      * Flushes the binary output stream, padding 0s if number of bits written so far      * is not a multiple of 8.      */      public   void  flush ()   {         clearBuffer ();          try   {             out . flush ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Flushes and closes the binary output stream.      * Once it is closed, bits can no longer be written.      */      public   void  close ()   {         flush ();          try   {             out . close ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Writes the specified bit to the binary output stream.      *  @param  x the { @code  boolean} to write      */      public   void  write ( boolean  x )   {         writeBit ( x );      }       /**      * Writes the 8-bit byte to the binary output stream.      *  @param  x the { @code  byte} to write.      */      public   void  write ( byte  x )   {         writeByte ( x  &   0xff );      }     /**      * Writes the 32-bit int to the binary output stream.      *  @param  x the { @code  int} to write      */      public   void  write ( int  x )   {         writeByte (( x  >>>
 
24
)
 
&
 
0xff
);

        writeByte
((

>>>
 
16
)
 
&
 
0xff
);

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the r-bit int to the binary output stream.

     *

     * 
@param
  x the {
@code
 int} to write

     * 
@param
  r the number of relevant bits in the char

     * 
@throws
 IllegalArgumentException unless {
@code
 r} is between 1 and 32

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is between 0 and 2r – 1

     */

    
public
 
void
 write
(
int
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
32
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the 64-bit double to the binary output stream.

     * 
@param
 x the {
@code
 double} to write

     */

    
public
 
void
 write
(
double
 x
)
 
{

        write
(
Double
.
doubleToRawLongBits
(
x
));

    
}

   
/**

     * Writes the 64-bit long to the binary output stream.

     * 
@param
 x the {
@code
 long} to write

     */

    
public
 
void
 write
(
long
 x
)
 
{

        writeByte
((
int
)
 
((

>>>
 
56
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
48
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
40
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
32
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
24
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
16
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
8
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
0
)
 
&
 
0xff
));

    
}

   
/**

     * Writes the 32-bit float to the binary output stream.

     * 
@param
 x the {
@code
 float} to write

     */

    
public
 
void
 write
(
float
 x
)
 
{

        write
(
Float
.
floatToRawIntBits
(
x
));

    
}

   
/**

     * Write the 16-bit int to the binary output stream.

     * 
@param
 x the {
@code
 short} to write.

     */

    
public
 
void
 write
(
short
 x
)
 
{

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the 8-bit char to the binary output stream.

     *

     * 
@param
  x the {
@code
 char} to write

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is betwen 0 and 255

     */

    
public
 
void
 write
(
char
 x
)
 
{

        
if
 
(

<   0   ||  x  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal 8-bit char = ”
 
+
 x
);

        writeByte
(
x
);

    
}

   
/**

     * Writes the r-bit char to the binary output stream.

     *

     * 
@param
  x the {
@code
 char} to write

     * 
@param
  r the number of relevant bits in the char

     * 
@throws
 IllegalArgumentException unless {
@code
 r} is between 1 and 16

     * 
@throws
 IllegalArgumentException unless {
@code
 x} is between 0 and 2r – 1

     */

    
public
 
void
 write
(
char
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
8
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the string of 8-bit characters to the binary output stream.

     *

     * 
@param
  s the {
@code
 String} to write

     * 
@throws
 IllegalArgumentException if any character in the string is not

     *         between 0 and 255

     */

    
public
 
void
 write
(
String
 s
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ));      }     /**      * Writes the string of r-bit characters to the binary output stream.      *  @param   s the { @code  String} to write      *  @param   r the number of relevants bits in each character      *  @throws  IllegalArgumentException unless r is between 1 and 16      *  @throws  IllegalArgumentException if any character in the string is not      *         between 0 and 2r – 1

     */

    
public
 
void
 write
(
String
 s
,
 
int
 r
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ),  r );      }     /**      * Test client. Read bits from standard input and write to the file      * specified on command line.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // create binary output stream to write to file          String  filename  =  args [ 0 ];          BinaryOut  out  =   new   BinaryOut ( filename );          BinaryIn   in   =   new   BinaryIn ();          // read from standard input and write to file          while   ( ! in . isEmpty ())   {              char  c  =  in . readChar ();             out . write ( c );          }         out . flush ();      } } BinaryStdIn.java BinaryStdIn.java /******************************************************************************  *  Compilation:  javac BinaryStdIn.java  *  Execution:    java BinaryStdIn < input > output

 *  Dependencies: none             

 *  

 *  Supports reading binary data from standard input.

 *

 *  % java BinaryStdIn < input  > output

 *  % diff input  output

 *

 ******************************************************************************/

import
 java
.
io
.
BufferedInputStream
;

import
 java
.
io
.
IOException
;

import
 java
.
util
.
NoSuchElementException
;

/**

 *  Binary standard input. This class provides methods for reading

 *  in bits from standard input, either one bit at a time (as a {
@code
 boolean}),

 *  8 bits at a time (as a {
@code
 byte} or {
@code
 char}),

 *  16 bits at a time (as a {
@code
 short}), 32 bits at a time

 *  (as an {
@code
 int} or {
@code
 float}), or 64 bits at a time (as a

 *  {
@code
 double} or {
@code
 long}).

 *  

 *  All primitive types are assumed to be represented using their 

 *  standard Java representations, in big-endian (most significant

 *  byte first) order.

 *  

 *  The client should not intermix calls to {
@code
 BinaryStdIn} with calls

 *  to {
@code
 StdIn} or {
@code
 System.in};

 *  otherwise unexpected behavior will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryStdIn
 
{

    
private
 
static
 
final
 
int
 EOF 
=
 

1
;
      
// end of file

    
private
 
static
 
BufferedInputStream
 in
;
  
// input stream

    
private
 
static
 
int
 buffer
;
              
// one character buffer

    
private
 
static
 
int
 n
;
                   
// number of bits left in buffer

    
private
 
static
 
boolean
 isInitialized
;
   
// has BinaryStdIn been called for first time?

    
// don’t instantiate

    
private
 
BinaryStdIn
()
 
{
 
}

    
// fill buffer

    
private
 
static
 
void
 initialize
()
 
{

        in 
=
 
new
 
BufferedInputStream
(
System
.
in
);

        buffer 
=
 
0
;

        n 
=
 
0
;

        fillBuffer
();

        isInitialized 
=
 
true
;

    
}

    
private
 
static
 
void
 fillBuffer
()
 
{

        
try
 
{

            buffer 
=
 in
.
read
();

            n 
=
 
8
;

        
}

        
catch
 
(
IOException
 e
)
 
{

            
System
.
out
.
println
(
“EOF”
);

            buffer 
=
 EOF
;

            n 
=
 

1
;

        
}

    
}

   
/**

     * Close this input stream and release any associated system resources.

     */

    
public
 
static
 
void
 close
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
try
 
{

            in
.
close
();

            isInitialized 
=
 
false
;

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalStateException
(
“Could not close BinaryStdIn”
,
 ioe
);

        
}

    
}

   
/**

     * Returns true if standard input is empty.

     * 
@return
 true if and only if standard input is empty

     */

    
public
 
static
 
boolean
 isEmpty
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
return
 buffer 
==
 EOF
;

    
}

   
/**

     * Reads the next bit of data from standard input and return as a boolean.

     *

     * 
@return
 the next bit of data from standard input as a {
@code
 boolean}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
boolean
 readBoolean
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        n

;

        
boolean
 bit 
=
 
((
buffer 
>>
 n
)
 
&
 
1
)
 
==
 
1
;

        
if
 
(

==
 
0
)
 fillBuffer
();

        
return
 bit
;

    
}

   
/**

     * Reads the next 8 bits from standard input and return as an 8-bit char.

     * Note that {
@code
 char} is a 16-bit type;

     * to read the next 16 bits as a char, use {
@code
 readChar(16)}.

     *

     * 
@return
 the next 8 bits of data from standard input as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than 8 bits available on standard input

     */

    
public
 
static
 
char
 readChar
()
 
{

        
if
 
(
isEmpty
())
 
throw
 
new
 
NoSuchElementException
(
“Reading from empty input stream”
);

        
// special case when aligned byte

        
if
 
(

==
 
8
)
 
{

            
int
 x 
=
 buffer
;

            fillBuffer
();

            
return
 
(
char
)
 
(

&
 
0xff
);

        
}

        
// combine last n bits of current buffer with first 8-n bits of new buffer

        
int
 x 
=
 buffer
;

        x 
<<=   ( 8   -  n );          int  oldN  =  n ;         fillBuffer ();          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );         n  =  oldN ;         x  |=   ( buffer  >>>
 n
);

        
return
 
(
char
)
 
(

&
 
0xff
);

        
// the above code doesn’t quite work for the last character if n = 8

        
// because buffer will be -1, so there is a special case for aligned byte

    
}

   
/**

     * Reads the next r bits from standard input and return as an r-bit character.

     *

     * 
@param
  r number of bits to read.

     * 
@return
 the next r bits of data from standard input as a {
@code
 char}

     * 
@throws
 NoSuchElementException if there are fewer than {
@code
 r} bits available on standard input

     * 
@throws
 IllegalArgumentException unless {
@code
 1 <= r <= 16}      */      public   static   char  readChar ( int  r )   {          if   ( r  <   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 8 case

        
if
 
(

==
 
8
)
 
return
 readChar
();

        
char
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the remaining bytes of data from standard input and return as a string.       *      *  @return  the remaining bytes of data from standard input as a { @code  String}      *  @throws  NoSuchElementException if standard input is empty or if the number of bits      *         available on standard input is not a multiple of 8 (byte-aligned)      */      public   static   String  readString ()   {          if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );          StringBuilder  sb  =   new   StringBuilder ();          while   ( ! isEmpty ())   {              char  c  =  readChar ();             sb . append ( c );          }          return  sb . toString ();      }     /**      * Reads the next 16 bits from standard input and return as a 16-bit short.      *      *  @return  the next 16 bits of data from standard input as a { @code  short}      *  @throws  NoSuchElementException if there are fewer than 16 bits available on standard input      */      public   static   short  readShort ()   {          short  x  =   0 ;          for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 32 bits from standard input and return as a 32-bit int.      *      *  @return  the next 32 bits of data from standard input as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input      */      public   static   int  readInt ()   {          int  x  =   0 ;          for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next r bits from standard input and return as an r-bit int.      *      *  @param   r number of bits to read.      *  @return  the next r bits of data from standard input as a { @code  int}      *  @throws  NoSuchElementException if there are fewer than { @code  r} bits available on standard input      *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}      */      public   static   int  readInt ( int  r )   {          if   ( r  <   1   ||  r  >
 
32
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value of r = ”
 
+
 r
);

        
// optimize r = 32 case

        
if
 
(

==
 
32
)
 
return
 readInt
();

        
int
 x 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  r ;  i ++ )   {             x  <<=   1 ;              boolean  bit  =  readBoolean ();              if   ( bit )  x  |=   1 ;          }          return  x ;      }     /**      * Reads the next 64 bits from standard input and return as a 64-bit long.      *      *  @return  the next 64 bits of data from standard input as a { @code  long}      *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input      */      public   static   long  readLong ()   {          long  x  =   0 ;          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              char  c  =  readChar ();             x  <<=   8 ;             x  |=  c ;          }          return  x ;      }     /**      * Reads the next 64 bits from standard input and return as a 64-bit double.      *      *  @return  the next 64 bits of data from standard input as a { @code  double}      *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input      */      public   static   double  readDouble ()   {          return   Double . longBitsToDouble ( readLong ());      }     /**      * Reads the next 32 bits from standard input and return as a 32-bit float.      *      *  @return  the next 32 bits of data from standard input as a { @code  float}      *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input      */      public   static   float  readFloat ()   {          return   Float . intBitsToFloat ( readInt ());      }     /**      * Reads the next 8 bits from standard input and return as an 8-bit byte.      *      *  @return  the next 8 bits of data from standard input as a { @code  byte}      *  @throws  NoSuchElementException if there are fewer than 8 bits available on standard input      */      public   static   byte  readByte ()   {          char  c  =  readChar ();          return   ( byte )   ( c  &   0xff );      }          /**      * Test client. Reads in a binary input file from standard input and writes      * it to standard output.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read one 8-bit char at a time          while   ( ! BinaryStdIn . isEmpty ())   {              char  c  =   BinaryStdIn . readChar ();              BinaryStdOut . write ( c );          }          BinaryStdOut . flush ();      } } BinaryStdOut.java BinaryStdOut.java /******************************************************************************  *  Compilation:  javac BinaryStdOut.java  *  Execution:    java BinaryStdOut  *  Dependencies: none  *  *  Write binary data to standard output, either one 1-bit boolean,  *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,  *  or one 64-bit long at a time.  *  *  The bytes written are not aligned.  *  ******************************************************************************/ import  java . io . BufferedOutputStream ; import  java . io . IOException ; /**  *  Binary standard output. This class provides methods for converting

 *  primtive type variables ({
@code
 boolean}, {
@code
 byte}, {
@code
 char},

 *  {
@code
 int}, {
@code
 long}, {
@code
 float}, and {
@code
 double})

 *  to sequences of bits and writing them to standard output.

 *  Uses big-endian (most-significant byte first).

 *  

 *  The client must {
@code
 flush()} the output stream when finished writing bits.

 *  

 *  The client should not intermix calls to {
@code
 BinaryStdOut} with calls

 *  to {
@code
 StdOut} or {
@code
 System.out}; otherwise unexpected behavior 

 *  will result.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
BinaryStdOut
 
{

    
private
 
static
 
BufferedOutputStream
 out
;
  
// output stream (standard output)

    
private
 
static
 
int
 buffer
;
                
// 8-bit buffer of bits to write

    
private
 
static
 
int
 n
;
                     
// number of bits remaining in buffer

    
private
 
static
 
boolean
 isInitialized
;
     
// has BinaryStdOut been called for first time?

    
// don’t instantiate

    
private
 
BinaryStdOut
()
 
{
 
}

    
// initialize BinaryStdOut

    
private
 
static
 
void
 initialize
()
 
{

        out 
=
 
new
 
BufferedOutputStream
(
System
.
out
);

        buffer 
=
 
0
;

        n 
=
 
0
;

        isInitialized 
=
 
true
;

    
}

   
/**

     * Writes the specified bit to standard output.

     */

    
private
 
static
 
void
 writeBit
(
boolean
 bit
)
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
// add bit to buffer

        buffer 
<<=   1 ;          if   ( bit )  buffer  |=   1 ;          // if buffer is full (8 bits), write out as a single byte         n ++ ;          if   ( n  ==   8 )  clearBuffer ();      }       /**      * Writes the 8-bit byte to standard output.      */      private   static   void  writeByte ( int  x )   {          if   ( ! isInitialized )  initialize ();          assert  x  >=
 
0
 
&&
 x 
<   256 ;          // optimized if byte-aligned          if   ( n  ==   0 )   {              try   {                 out . write ( x );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }              return ;          }          // otherwise write one bit at a time          for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(
8
 

 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

    
// write out any remaining bits in buffer to standard output, padding with 0s

    
private
 
static
 
void
 clearBuffer
()
 
{

        
if
 
(
!
isInitialized
)
 initialize
();

        
if
 
(

==
 
0
)
 
return
;

        
if
 
(

>
 
0
)
 buffer 
<<=   ( 8   -  n );          try   {             out . write ( buffer );          }          catch   ( IOException  e )   {             e . printStackTrace ();          }         n  =   0 ;         buffer  =   0 ;      }     /**      * Flushes standard output, padding 0s if number of bits written so far      * is not a multiple of 8.      */      public   static   void  flush ()   {         clearBuffer ();          try   {             out . flush ();          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Flushes and closes standard output. Once standard output is closed, you can no      * longer write bits to it.      */      public   static   void  close ()   {         flush ();          try   {             out . close ();             isInitialized  =   false ;          }          catch   ( IOException  e )   {             e . printStackTrace ();          }      }     /**      * Writes the specified bit to standard output.      *  @param  x the { @code  boolean} to write.      */      public   static   void  write ( boolean  x )   {         writeBit ( x );      }       /**      * Writes the 8-bit byte to standard output.      *  @param  x the { @code  byte} to write.      */      public   static   void  write ( byte  x )   {         writeByte ( x  &   0xff );      }     /**      * Writes the 32-bit int to standard output.      *  @param  x the { @code  int} to write.      */      public   static   void  write ( int  x )   {         writeByte (( x  >>>
 
24
)
 
&
 
0xff
);

        writeByte
((

>>>
 
16
)
 
&
 
0xff
);

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the r-bit int to standard output.

     * 
@param
 x the {
@code
 int} to write.

     * 
@param
 r the number of relevant bits in the char.

     * 
@throws
 IllegalArgumentException if {
@code
 r} is not between 1 and 32.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
int
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
32
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
32
)
        
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

<   0   ||  x  >=
 
(
1
 
<<  r ))   throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the 64-bit double to standard output.

     * 
@param
 x the {
@code
 double} to write.

     */

    
public
 
static
 
void
 write
(
double
 x
)
 
{

        write
(
Double
.
doubleToRawLongBits
(
x
));

    
}

   
/**

     * Writes the 64-bit long to standard output.

     * 
@param
 x the {
@code
 long} to write.

     */

    
public
 
static
 
void
 write
(
long
 x
)
 
{

        writeByte
((
int
)
 
((

>>>
 
56
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
48
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
40
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
32
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
24
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
 
16
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
8
)
 
&
 
0xff
));

        writeByte
((
int
)
 
((

>>>
  
0
)
 
&
 
0xff
));

    
}

   
/**

     * Writes the 32-bit float to standard output.

     * 
@param
 x the {
@code
 float} to write.

     */

    
public
 
static
 
void
 write
(
float
 x
)
 
{

        write
(
Float
.
floatToRawIntBits
(
x
));

    
}

   
/**

     * Writes the 16-bit int to standard output.

     * 
@param
 x the {
@code
 short} to write.

     */

    
public
 
static
 
void
 write
(
short
 x
)
 
{

        writeByte
((

>>>
  
8
)
 
&
 
0xff
);

        writeByte
((

>>>
  
0
)
 
&
 
0xff
);

    
}

   
/**

     * Writes the 8-bit char to standard output.

     * 
@param
 x the {
@code
 char} to write.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not betwen 0 and 255.

     */

    
public
 
static
 
void
 write
(
char
 x
)
 
{

        
if
 
(

<   0   ||  x  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal 8-bit char = ”
 
+
 x
);

        writeByte
(
x
);

    
}

   
/**

     * Writes the r-bit char to standard output.

     * 
@param
 x the {
@code
 char} to write.

     * 
@param
 r the number of relevant bits in the char.

     * 
@throws
 IllegalArgumentException if {
@code
 r} is not between 1 and 16.

     * 
@throws
 IllegalArgumentException if {
@code
 x} is not between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
char
 x
,
 
int
 r
)
 
{

        
if
 
(

==
 
8
)
 
{

            write
(
x
);

            
return
;

        
}

        
if
 
(

<   1   ||  r  >
 
16
)
 
throw
 
new
 
IllegalArgumentException
(
“Illegal value for r = ”
 
+
 r
);

        
if
 
(

>=
 
(
1
 
<<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );          for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {              boolean  bit  =   (( x  >>>
 
(


 i 

 
1
))
 
&
 
1
)
 
==
 
1
;

            writeBit
(
bit
);

        
}

    
}

   
/**

     * Writes the string of 8-bit characters to standard output.

     * 
@param
 s the {
@code
 String} to write.

     * 
@throws
 IllegalArgumentException if any character in the string is not

     * between 0 and 255.

     */

    
public
 
static
 
void
 write
(
String
 s
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ));      }     /**      * Writes the string of r-bit characters to standard output.      *  @param  s the { @code  String} to write.      *  @param  r the number of relevants bits in each character.      *  @throws  IllegalArgumentException if r is not between 1 and 16.      *  @throws  IllegalArgumentException if any character in the string is not      * between 0 and 2r – 1.

     */

    
public
 
static
 
void
 write
(
String
 s
,
 
int
 r
)
 
{

        
for
 
(
int
 i 
=
 
0
;
 i 
<  s . length ();  i ++ )             write ( s . charAt ( i ),  r );      }     /**      * Tests the methods in this class.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          int  m  =   Integer . parseInt ( args [ 0 ]);          // write n integers to binary standard output          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              BinaryStdOut . write ( i );          }          BinaryStdOut . flush ();      } } Draw.java Draw.java /******************************************************************************  *  Compilation:  javac Draw.java  *  Execution:    java Draw  *  Dependencies: none  *  *  Drawing library. This class provides a basic capability for creating  *  drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of points, lines, and curves  *  in a window on your computer and to save the drawings to a file.  *  This is the object-oriented version of standard draw; it supports  *  multiple indepedent drawing windows.  *  *  Todo  *  ----  *    -  Add support for gradient fill, etc.  *  *  Remarks  *  -------  *    -  don't use AffineTransform for rescaling since it inverts  *       images and strings  *    -  careful using setFont in inner loop within an animation -  *       it can cause flicker  *  ******************************************************************************/ import  java . awt . BasicStroke ; import  java . awt . Color ; import  java . awt . Component ; import  java . awt . FileDialog ; import  java . awt . Font ; import  java . awt . FontMetrics ; import  java . awt . Graphics ; import  java . awt . Graphics2D ; import  java . awt . Image ; import  java . awt . MediaTracker ; import  java . awt . RenderingHints ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . MouseEvent ; import  java . awt . event . MouseListener ; import  java . awt . event . MouseMotionListener ; import  java . awt . event . KeyEvent ; import  java . awt . event . KeyListener ; import  java . awt . geom . Arc2D ; import  java . awt . geom . Ellipse2D ; import  java . awt . geom . GeneralPath ; import  java . awt . geom . Line2D ; import  java . awt . geom . Rectangle2D ; import  java . awt . image . BufferedImage ; import  java . awt . image . DirectColorModel ; import  java . awt . image . WritableRaster ; import  java . io . File ; import  java . io . IOException ; import  java . net . MalformedURLException ; import  java . net . URL ; import  java . util . ArrayList ; import  java . util . LinkedList ; import  java . util . TreeSet ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . KeyStroke ; /**  *  Draw. This class provides a basic capability for

 *  creating drawings with your programs. It uses a simple graphics model that

 *  allows you to create drawings consisting of points, lines, and curves

 *  in a window on your computer and to save the drawings to a file.

 *  This is the object-oriented version of standard draw; it supports

 *  multiple indepedent drawing windows.

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
Draw
 
implements
 
ActionListener
,
 
MouseListener
,
 
MouseMotionListener
,
 
KeyListener
 
{

    
/**

     *  The color black.

     */

    
public
 
static
 
final
 
Color
 BLACK 
=
 
Color
.
BLACK
;

    
/**

     *  The color blue.

     */

    
public
 
static
 
final
 
Color
 BLUE 
=
 
Color
.
BLUE
;

    
/**

     *  The color cyan.

     */

    
public
 
static
 
final
 
Color
 CYAN 
=
 
Color
.
CYAN
;

    
/**

     *  The color dark gray.

     */

    
public
 
static
 
final
 
Color
 DARK_GRAY 
=
 
Color
.
DARK_GRAY
;

    
/**

     *  The color gray.

     */

    
public
 
static
 
final
 
Color
 GRAY 
=
 
Color
.
GRAY
;

    
/**

     *  The color green.

     */

    
public
 
static
 
final
 
Color
 GREEN  
=
 
Color
.
GREEN
;

    
/**

     *  The color light gray.

     */

    
public
 
static
 
final
 
Color
 LIGHT_GRAY 
=
 
Color
.
LIGHT_GRAY
;

    
/**

     *  The color magenta.

     */

    
public
 
static
 
final
 
Color
 MAGENTA 
=
 
Color
.
MAGENTA
;

    
/**

     *  The color orange.

     */

    
public
 
static
 
final
 
Color
 ORANGE 
=
 
Color
.
ORANGE
;

    
/**

     *  The color pink.

     */

    
public
 
static
 
final
 
Color
 PINK 
=
 
Color
.
PINK
;

    
/**

     *  The color red.

     */

    
public
 
static
 
final
 
Color
 RED 
=
 
Color
.
RED
;

    
/**

     *  The color white.

     */

    
public
 
static
 
final
 
Color
 WHITE 
=
 
Color
.
WHITE
;

    
/**

     *  The color yellow.

     */

    
public
 
static
 
final
 
Color
 YELLOW 
=
 
Color
.
YELLOW
;

    
/**

     * Shade of blue used in Introduction to Programming in Java.

     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).

     */

    
public
 
static
 
final
 
Color
 BOOK_BLUE 
=
 
new
 
Color
(
9
,
 
90
,
 
166
);

    
/**

     * Shade of light blue used in Introduction to Programming in Java.

     * The RGB values are approximately (103, 198, 243).

     */

    
public
 
static
 
final
 
Color
 BOOK_LIGHT_BLUE 
=
 
new
 
Color
(
103
,
 
198
,
 
243
);

    

    
/**

     * Shade of red used in Algorithms, 4th edition.

     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).

     */

    
public
 
static
 
final
 
Color
 BOOK_RED 
=
 
new
 
Color
(
150
,
 
35
,
 
31
);

    
/**

     * Shade of orange used in Princeton’s identity.

     * It is PMS 158. The RGB values are approximately (245, 128, 37).

     */

    
public
 
static
 
final
 
Color
 PRINCETON_ORANGE 
=
 
new
 
Color
(
245
,
 
128
,
 
37
);

    
// default colors

    
private
 
static
 
final
 
Color
 DEFAULT_PEN_COLOR   
=
 BLACK
;

    
private
 
static
 
final
 
Color
 DEFAULT_CLEAR_COLOR 
=
 WHITE
;

    
// boundary of drawing canvas, 0% border

    
private
 
static
 
final
 
double
 BORDER 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMAX 
=
 
1.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMAX 
=
 
1.0
;

    
// default canvas size is SIZE-by-SIZE

    
private
 
static
 
final
 
int
 DEFAULT_SIZE 
=
 
512
;

    
// default pen radius

    
private
 
static
 
final
 
double
 DEFAULT_PEN_RADIUS 
=
 
0.002
;

    
// default font

    
private
 
static
 
final
 
Font
 DEFAULT_FONT 
=
 
new
 
Font
(
“SansSerif”
,
 
Font
.
PLAIN
,
 
16
);

    
// current pen color

    
private
 
Color
 penColor
;

    
// canvas size

    
private
 
int
 width  
=
 DEFAULT_SIZE
;

    
private
 
int
 height 
=
 DEFAULT_SIZE
;

    
// current pen radius

    
private
 
double
 penRadius
;

    
// show we draw immediately or wait until next show?

    
private
 
boolean
 defer 
=
 
false
;

    
private
 
double
 xmin
,
 ymin
,
 xmax
,
 ymax
;

    
// name of window

    
private
 
String
 name 
=
 
“Draw”
;

    
// for synchronization

    
private
 
final
 
Object
 mouseLock 
=
 
new
 
Object
();

    
private
 
final
 
Object
 keyLock 
=
 
new
 
Object
();

    
// current font

    
private
 
Font
 font
;

    
// the JLabel for drawing

    
private
 
JLabel
 draw
;

    
// double buffered graphics

    
private
 
BufferedImage
 offscreenImage
,
 onscreenImage
;

    
private
 
Graphics2D
 offscreen
,
 onscreen
;

    
// the frame for drawing to the screen

    
private
 
JFrame
 frame 
=
 
new
 
JFrame
();

    
// mouse state

    
private
 
boolean
 isMousePressed 
=
 
false
;

    
private
 
double
 mouseX 
=
 
0
;

    
private
 
double
 mouseY 
=
 
0
;

    
// keyboard state

    
private
 
final
 
LinkedList
< Character >
 keysTyped 
=
 
new
 
LinkedList
< Character >
();

    
private
 
final
 
TreeSet
< Integer >
 keysDown 
=
 
new
 
TreeSet
< Integer >
();

    
// event-based listeners

    
private
 
final
 
ArrayList
< DrawListener >
 listeners 
=
 
new
 
ArrayList
< DrawListener >
();

    
/**

     * Initializes an empty drawing object with the given name.

     *

     * 
@param
 name the title of the drawing window.

     */

    
public
 
Draw
(
String
 name
)
 
{

        
this
.
name 
=
 name
;

        init
();

    
}

    
/**

     * Initializes an empty drawing object.

     */

    
public
 
Draw
()
 
{

        init
();

    
}

    
private
 
void
 init
()
 
{

        
if
 
(
frame 
!=
 
null
)
 frame
.
setVisible
(
false
);

        frame 
=
 
new
 
JFrame
();

        offscreenImage 
=
 
new
 
BufferedImage
(
2
*
width
,
 
2
*
height
,
 
BufferedImage
.
TYPE_INT_ARGB
);

        onscreenImage  
=
 
new
 
BufferedImage
(
2
*
width
,
 
2
*
height
,
 
BufferedImage
.
TYPE_INT_ARGB
);

        offscreen 
=
 offscreenImage
.
createGraphics
();

        onscreen  
=
 onscreenImage
.
createGraphics
();

        offscreen
.
scale
(
2.0
,
 
2.0
);
  
// since we made it 2x as big

        setXscale
();

        setYscale
();

        offscreen
.
setColor
(
DEFAULT_CLEAR_COLOR
);

        offscreen
.
fillRect
(
0
,
 
0
,
 width
,
 height
);

        setPenColor
();

        setPenRadius
();

        setFont
();

        clear
();

        
// add antialiasing

        
RenderingHints
 hints 
=
 
new
 
RenderingHints
(
RenderingHints
.
KEY_ANTIALIASING
,

                                                  
RenderingHints
.
VALUE_ANTIALIAS_ON
);

        hints
.
put
(
RenderingHints
.
KEY_RENDERING
,
 
RenderingHints
.
VALUE_RENDER_QUALITY
);

        offscreen
.
addRenderingHints
(
hints
);

        
// frame stuff

        
RetinaImageIcon
 icon 
=
 
new
 
RetinaImageIcon
(
onscreenImage
);

        draw 
=
 
new
 
JLabel
(
icon
);

        draw
.
addMouseListener
(
this
);

        draw
.
addMouseMotionListener
(
this
);

        frame
.
setContentPane
(
draw
);

        frame
.
addKeyListener
(
this
);
    
// JLabel cannot get keyboard focus

        frame
.
setResizable
(
false
);

        
// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            // closes all windows

        frame
.
setDefaultCloseOperation
(
JFrame
.
DISPOSE_ON_CLOSE
);
      
// closes only current window

        frame
.
setFocusTraversalKeysEnabled
(
false
);
  
// to recognize VK_TAB with isKeyPressed()

        frame
.
setTitle
(
name
);

        frame
.
setJMenuBar
(
createMenuBar
());

        frame
.
pack
();

        frame
.
requestFocusInWindow
();

        frame
.
setVisible
(
true
);

    
}

    
/**

     * Sets the upper-left hand corner of the drawing window to be (x, y), where (0, 0) is upper left.

     *

     * 
@param
  x the number of pixels from the left

     * 
@param
  y the number of pixels from the top

     * 
@throws
 IllegalArgumentException if the width or height is 0 or negative

     */

    
public
 
void
 setLocationOnScreen
(
int
 x
,
 
int
 y
)
 
{

        
if
 
(

<=   0   ||  y  <=   0 )   throw   new   IllegalArgumentException ();         frame . setLocation ( x ,  y );      }      /**      * Sets the default close operation.      *      *  @param   value the value, typically { @code  JFrame.EXIT_ON_CLOSE}      *         (close all windows) or { @code  JFrame.DISPOSE_ON_CLOSE}      *         (close current window)      */      public   void  setDefaultCloseOperation ( int  value )   {         frame . setDefaultCloseOperation ( value );      }              /**      * Sets the canvas (drawing area) to be width-by-height pixels.

     * This also erases the current drawing and resets the coordinate system, pen radius,

     * pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning of a program.

     *

     * 
@param
  canvasWidth the width as a number of pixels

     * 
@param
  canvasHeight the height as a number of pixels

     * 
@throws
 IllegalArgumentException unless both {
@code
 canvasWidth}

     *         and {
@code
 canvasHeight} are positive

     */

    
public
 
void
 setCanvasSize
(
int
 canvasWidth
,
 
int
 canvasHeight
)
 
{

        
if
 
(
canvasWidth 
<   1   ||  canvasHeight  <   1 )   {              throw   new   IllegalArgumentException ( "width and height must be positive" );          }         width  =  canvasWidth ;         height  =  canvasHeight ;         init ();      }      // create the menu bar (changed to private)      private   JMenuBar  createMenuBar ()   {          JMenuBar  menuBar  =   new   JMenuBar ();          JMenu  menu  =   new   JMenu ( "File" );         menuBar . add ( menu );          JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );         menuItem1 . addActionListener ( this );          // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()         menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                  Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));         menu . add ( menuItem1 );          return  menuBar ;      }     /***************************************************************************     *  User and screen coordinate systems.     ***************************************************************************/      // throw an IllegalArgumentException if x is NaN or infinite      private   static   void  validate ( double  x ,   String  name )   {          if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );          if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNonnegative ( double  x ,   String  name )   {          if   ( x  <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNotNull ( Object  x ,   String  name )   {          if   ( x  ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );      }      /**      * Sets the x-scale to be the default (between 0.0 and 1.0).      */      public   void  setXscale ()   {         setXscale ( DEFAULT_XMIN ,  DEFAULT_XMAX );      }      /**      * Sets the y-scale to be the default (between 0.0 and 1.0).      */      public   void  setYscale ()   {         setYscale ( DEFAULT_YMIN ,  DEFAULT_YMAX );      }      /**      * Sets the x-scale.      *      *  @param  min the minimum value of the x-scale      *  @param  max the maximum value of the x-scale      *  @throws  IllegalArgumentException if { @code  (max == min)}      *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite      */      public   void  setXscale ( double  min ,   double  max )   {         validate ( min ,   "min" );         validate ( max ,   "max" );          double  size  =  max  -  min ;          if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );         xmin  =  min  -  BORDER  *  size ;         xmax  =  max  +  BORDER  *  size ;      }      /**      * Sets the y-scale.      *      *  @param  min the minimum value of the y-scale      *  @param  max the maximum value of the y-scale      *  @throws  IllegalArgumentException if { @code  (max == min)}      *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite      */      public   void  setYscale ( double  min ,   double  max )   {         validate ( min ,   "min" );         validate ( max ,   "max" );          double  size  =  max  -  min ;          if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );         ymin  =  min  -  BORDER  *  size ;         ymax  =  max  +  BORDER  *  size ;      }      // helper functions that scale from user coordinates to screen coordinates and back      private   double   scaleX ( double  x )   {   return  width   *   ( x  -  xmin )   /   ( xmax  -  xmin );   }      private   double   scaleY ( double  y )   {   return  height  *   ( ymax  -  y )   /   ( ymax  -  ymin );   }      private   double  factorX ( double  w )   {   return  w  *  width   /   Math . abs ( xmax  -  xmin );    }      private   double  factorY ( double  h )   {   return  h  *  height  /   Math . abs ( ymax  -  ymin );    }      private   double    userX ( double  x )   {   return  xmin  +  x  *   ( xmax  -  xmin )   /  width ;      }      private   double    userY ( double  y )   {   return  ymax  -  y  *   ( ymax  -  ymin )   /  height ;     }      /**      * Clears the screen to the default color (white).      */      public   void  clear ()   {         clear ( DEFAULT_CLEAR_COLOR );      }      /**      * Clears the screen to the given color.      *      *  @param  color the color to make the background      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  clear ( Color  color )   {         validateNotNull ( color ,   "color" );         offscreen . setColor ( color );         offscreen . fillRect ( 0 ,   0 ,  width ,  height );         offscreen . setColor ( penColor );         draw ();      }      /**      * Gets the current pen radius.      *      *  @return  the current pen radius      */      public   double  getPenRadius ()   {          return  penRadius ;      }      /**      * Sets the pen size to the default (.002).      */      public   void  setPenRadius ()   {         setPenRadius ( DEFAULT_PEN_RADIUS );      }      /**      * Sets the radius of the pen to the given size.      *      *  @param   radius the radius of the pen      *  @throws  IllegalArgumentException if { @code  radius} is negative, NaN, or infinite      */      public   void  setPenRadius ( double  radius )   {         validate ( radius ,   "pen radius" );         validateNonnegative ( radius ,   "pen radius" );         penRadius  =  radius  *  DEFAULT_SIZE ;          BasicStroke  stroke  =   new   BasicStroke (( float )  penRadius ,   BasicStroke . CAP_ROUND ,   BasicStroke . JOIN_ROUND );          // BasicStroke stroke = new BasicStroke((float) penRadius);         offscreen . setStroke ( stroke );      }      /**      * Gets the current pen color.      *      *  @return  the current pen color      */      public   Color  getPenColor ()   {          return  penColor ;      }      /**      * Sets the pen color to the default color (black).      */      public   void  setPenColor ()   {         setPenColor ( DEFAULT_PEN_COLOR );      }      /**      * Sets the pen color to the given color.      *      *  @param  color the color to make the pen      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  setPenColor ( Color  color )   {         validateNotNull ( color ,   "color" );         penColor  =  color ;         offscreen . setColor ( penColor );      }      /**      * Sets the pen color to the given RGB color.      *      *  @param   red the amount of red (between 0 and 255)      *  @param   green the amount of green (between 0 and 255)      *  @param   blue the amount of blue (between 0 and 255)      *  @throws  IllegalArgumentException if { @code  red}, { @code  green},      *         or { @code  blue} is outside its prescribed range      */      public   void  setPenColor ( int  red ,   int  green ,   int  blue )   {          if   ( red    <   0   ||  red    >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“red must be between 0 and 255”
);

        
if
 
(
green 
<   0   ||  green  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“green must be between 0 and 255”
);

        
if
 
(
blue  
<   0   ||  blue   >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“blue must be between 0 and 255”
);

        setPenColor
(
new
 
Color
(
red
,
 green
,
 blue
));

    
}

    
/**

     * Turns on xor mode.

     */

    
public
 
void
 xorOn
()
 
{

        offscreen
.
setXORMode
(
DEFAULT_CLEAR_COLOR
);

    
}

    
/**

     * Turns off xor mode.

     */

    
public
 
void
 xorOff
()
 
{

        offscreen
.
setPaintMode
();

    
}

    
/**

     * Gets the current {
@code
 JLabel} for use in some other GUI.

     *

     * 
@return
 the current {
@code
 JLabel}

     */

    
public
 
JLabel
 getJLabel
()
 
{

        
return
 draw
;

    
}

    
/**

     * Gets the current font.

     *

     * 
@return
 the current font

     */

    
public
 
Font
 getFont
()
 
{

        
return
 font
;

    
}

    
/**

     * Sets the font to the default font (sans serif, 16 point).

     */

    
public
 
void
 setFont
()
 
{

        setFont
(
DEFAULT_FONT
);

    
}

    
/**

     * Sets the font to the given value.

     *

     * 
@param
 font the font

     * 
@throws
 IllegalArgumentException if {
@code
 font} is {
@code
 null}

     */

    
public
 
void
 setFont
(
Font
 font
)
 
{

        validateNotNull
(
font
,
 
“font”
);

        
this
.
font 
=
 font
;

    
}

   
/***************************************************************************

    *  Drawing geometric shapes.

    ***************************************************************************/

    
/**

     * Draws a line from (x0, y0) to (x1, y1).

     *

     * 
@param
 x0 the x-coordinate of the starting point

     * 
@param
 y0 the y-coordinate of the starting point

     * 
@param
 x1 the x-coordinate of the destination point

     * 
@param
 y1 the y-coordinate of the destination point

     * 
@throws
 IllegalArgumentException if any coordinate is either NaN or infinite

     */

    
public
 
void
 line
(
double
 x0
,
 
double
 y0
,
 
double
 x1
,
 
double
 y1
)
 
{

        validate
(
x0
,
 
“x0”
);

        validate
(
y0
,
 
“y0”
);

        validate
(
x1
,
 
“x1”
);

        validate
(
y1
,
 
“y1”
);

        offscreen
.
draw
(
new
 
Line2D
.
Double
(
scaleX
(
x0
),
 scaleY
(
y0
),
 scaleX
(
x1
),
 scaleY
(
y1
)));

        draw
();

    
}

    
/**

     * Draws one pixel at (x, y).

     *

     * 
@param
 x the x-coordinate of the pixel

     * 
@param
 y the y-coordinate of the pixel

     * 
@throws
 IllegalArgumentException if {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
private
 
void
 pixel
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        offscreen
.
fillRect
((
int
)
 
Math
.
round
(
scaleX
(
x
)),
 
(
int
)
 
Math
.
round
(
scaleY
(
y
)),
 
1
,
 
1
);

    
}

    
/**

     * Draws a point at (x, y).

     *

     * 
@param
 x the x-coordinate of the point

     * 
@param
 y the y-coordinate of the point

     * 
@throws
 IllegalArgumentException if either {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
public
 
void
 point
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 r 
=
 penRadius
;

        
// double ws = factorX(2*r);

        
// double hs = factorY(2*r);

        
// if (ws <= 1 && hs <= 1) pixel(x, y);          if   ( r  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  r / 2 ,  ys  -  r / 2 ,  r ,  r ));         draw ();      }      /**      * Draws a circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 circle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“radius”
);

        validateNonnegative
(
radius
,
 
“radius”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
radius
);

        
double
 hs 
=
 factorY
(
2
*
radius
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a filled circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 filledCircle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“radius”
);

        validateNonnegative
(
radius
,
 
“radius”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
radius
);

        
double
 hs 
=
 factorY
(
2
*
radius
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws an ellipse with the specified semimajor and semiminor axes,      * centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the ellipse

     * 
@param
  y the y-coordinate of the center of the ellipse

     * 
@param
  semiMajorAxis is the semimajor axis of the ellipse

     * 
@param
  semiMinorAxis is the semiminor axis of the ellipse

     * 
@throws
 IllegalArgumentException if either {
@code
 semiMajorAxis}

     *         or {
@code
 semiMinorAxis} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 ellipse
(
double
 x
,
 
double
 y
,
 
double
 semiMajorAxis
,
 
double
 semiMinorAxis
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
semiMajorAxis
,
 
“semimajor axis”
);

        validate
(
semiMinorAxis
,
 
“semiminor axis”
);

        validateNonnegative
(
semiMajorAxis
,
 
“semimajor axis”
);

        validateNonnegative
(
semiMinorAxis
,
 
“semiminor axis”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
semiMajorAxis
);

        
double
 hs 
=
 factorY
(
2
*
semiMinorAxis
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a filled ellipse with the specified semimajor and semiminor axes,      * centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the ellipse

     * 
@param
  y the y-coordinate of the center of the ellipse

     * 
@param
  semiMajorAxis is the semimajor axis of the ellipse

     * 
@param
  semiMinorAxis is the semiminor axis of the ellipse

     * 
@throws
 IllegalArgumentException if either {
@code
 semiMajorAxis}

     *         or {
@code
 semiMinorAxis} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 filledEllipse
(
double
 x
,
 
double
 y
,
 
double
 semiMajorAxis
,
 
double
 semiMinorAxis
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
semiMajorAxis
,
 
“semimajor axis”
);

        validate
(
semiMinorAxis
,
 
“semiminor axis”
);

        validateNonnegative
(
semiMajorAxis
,
 
“semimajor axis”
);

        validateNonnegative
(
semiMinorAxis
,
 
“semiminor axis”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
semiMajorAxis
);

        
double
 hs 
=
 factorY
(
2
*
semiMinorAxis
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a circular arc of the specified radius,      * centered at (xy), from angle1 to angle2 (in degrees).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@param
  angle1 the starting angle. 0 would mean an arc beginning at 3 o’clock.

     * 
@param
  angle2 the angle at the end of the arc. For example, if

     *         you want a 90 degree arc, then angle2 should be angle1 + 90.

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
void
 arc
(
double
 x
,
 
double
 y
,
 
double
 radius
,
 
double
 angle1
,
 
double
 angle2
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“arc radius”
);

        validate
(
angle1
,
 
“angle1”
);

        validate
(
angle2
,
 
“angle2”
);

        validateNonnegative
(
radius
,
 
“arc radius”
);

        
while
 
(
angle2 
<  angle1 )  angle2  +=   360 ;          double  xs  =  scaleX ( x );         double ys = scaleY(y);         double ws = factorX(2*radius);         double hs = factorY(2*radius);         if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Arc2D.Double(xs - ws/2, ys - hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void square(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void filledSquare(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void rectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public void filledRectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public void polygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.draw(path);         draw();     }     /**     * Draws a filled polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public void filledPolygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.fill(path);         draw();     }    /***************************************************************************    *  Drawing images.    ***************************************************************************/     // get an image from the given filename    private static Image getImage(String filename) {         if (filename == null) throw new IllegalArgumentException();         // to read from file        ImageIcon icon = new ImageIcon(filename);         // try to read from URL        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             try {                 URL url = new URL(filename);                 icon = new ImageIcon(url);             }             catch (MalformedURLException e) {                 /* not a url */             }         }         // in case file is inside a .jar (classpath relative to StdDraw)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource(filename);             if (url != null)                 icon = new ImageIcon(url);         }         // in case file is inside a .jar (classpath relative to root of jar)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = Draw.class.getResource("/" + filename);             if (url == null) throw new IllegalArgumentException("image " + filename + " not found");             icon = new ImageIcon(url);         }         return icon.getImage();     }     /**     * Draws the specified image centered at (xy).     * The supported image formats are JPEG, PNG, and GIF.     * As an optimization, the picture is cached, so there is no performance     * penalty for redrawing the same image multiple times (e.g., in an animation).     * However, if you change the picture file after drawing it, subsequent     * calls will draw the original picture.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if either {@code x} or {@code y} is either NaN or infinite     */

    public void picture(double x, double y, String filename) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(filename, “filename”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         draw();     }     /**     * Draws the specified image centered at (xy),     * rotated given number of degrees.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x}, {@code y}, {@code degrees} is NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void picture(double x, double y, String filename, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }     /**     * Draws the specified image centered at (xy),     * rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void picture(double x, double y, String filename, double scaledWidth, double scaledHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         else {             offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                        (int) Math.round(ys - hs/2.0),                                        (int) Math.round(ws),                                        (int) Math.round(hs), null);         }         draw();     }     /**     * Draws the specified image centered at (xy), rotated     * given number of degrees, and rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     */

    public void picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                    (int) Math.round(ys - hs/2.0),                                    (int) Math.round(ws),                                    (int) Math.round(hs), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }    /***************************************************************************    *  Drawing text.    ***************************************************************************/     /**     * Writes the given text string in the current font, centered at (xy).     *     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void text(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws/2.0), (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, centered at (xy) and     * rotated by the specified number of degrees.     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x}, {@code y}, or {@code degrees} is either NaN or infinite     */

    public void text(double x, double y, String text, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(text, “text”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        offscreen.rotate(Math.toRadians(-degrees), xs, ys);

        text(x, y, text);

        offscreen.rotate(Math.toRadians(+degrees), xs, ys);

    }

    /**     * Writes the given text string in the current font, left-aligned at (xy).     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void textLeft(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = metrics.stringWidth(text);        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) xs, (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, right-aligned at (xy).     *     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public void textRight(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws), (float) (ys + hs));

        draw();

    }

    /**     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds     * and enables double buffering.     * @param t number of milliseconds     * @deprecated replaced by {@link #enableDoubleBuffering()}, {@link #show()}, and {@link #pause(int t)}     */

    @Deprecated

    public void show(int t) {

        show();

        pause(t);

        enableDoubleBuffering();

    }

    /**     * Pause for t milliseconds. This method is intended to support computer animations.     * @param t number of milliseconds     */

    public void pause(int t) {

        try {

            Thread.sleep(t);

        }

        catch (InterruptedException e) {

            System.out.println(“Error sleeping”);

        }

    }

    /**     * Copies offscreen buffer to onscreen buffer. There is no reason to call     * this method unless double buffering is enabled.     */

    public void show() {

        onscreen.drawImage(offscreenImage, 0, 0, null);

        frame.repaint();

    }

    // draw onscreen if defer is false    private void draw() {

        if (!defer) show();

    }

    /**     * Enable double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be deferred until the next call     * to show(). Useful for animations.     */

    public void enableDoubleBuffering() {

        defer = true;

    }

    /**     * Disable double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be displayed on screen when called.     * This is the default.     */

    public void disableDoubleBuffering() {

        defer = false;

    }

    /**     * Saves the drawing to using the specified filename.     * The supported image formats are JPEG and PNG;     * the filename suffix must be {@code  } or {@code  }.     *     * @param  filename the name of the file with one of the required suffixes     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public void save(String filename) {

        validateNotNull(filename, “filename”);

        File file = new File(filename);

        String suffix = filename.substring(filename.lastIndexOf(‘.’) + 1);

        // png files        if (“png”.equalsIgnoreCase(suffix)) {

            try {

                ImageIO.write(offscreenImage, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        // need to change from ARGB to RGB for jpeg        // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727        else if (“jpg”.equalsIgnoreCase(suffix)) {

            WritableRaster raster = offscreenImage.getRaster();

            WritableRaster newRaster;

            newRaster = raster.createWritableChild(0, 0, width, height, 0, 0, new int[] {0, 1, 2});

            DirectColorModel cm = (DirectColorModel) offscreenImage.getColorModel();

            DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(),

                                                          cm.getRedMask(),

                                                          cm.getGreenMask(),

                                                          cm.getBlueMask());

            BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false,  null);

            try {

                ImageIO.write(rgbBuffer, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        else {

            System.out.println(“Invalid image file type: ” + suffix);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void actionPerformed(ActionEvent e) {

        FileDialog chooser = new FileDialog(frame, “Use a   or   extension”, FileDialog.SAVE);

        chooser.setVisible(true);

        String filename = chooser.getFile();

        if (filename != null) {

            save(chooser.getDirectory() + File.separator + chooser.getFile());

        }

    }

   /***************************************************************************    *  Event-based interactions.    ***************************************************************************/

    /**     * Adds a {@link DrawListener} to listen to keyboard and mouse events.     *     * @param listener the {\tt DrawListener} argument     */

    public void addListener(DrawListener listener) {

        // ensure there is a window for listenting to events        show();

        listeners.add(listener);

        frame.addKeyListener(this);

        frame.addMouseListener(this);

        frame.addMouseMotionListener(this);

        frame.setFocusable(true);     }

   /***************************************************************************    *  Mouse interactions.    ***************************************************************************/

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed;     *         {@code false} otherwise     */

    public boolean isMousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed;     *         {@code false} otherwise     * @deprecated replaced by {@link #isMousePressed()}     */

    @Deprecated

    public boolean mousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns the x-coordinate of the mouse.     * @return the x-coordinate of the mouse     */

    public double mouseX() {

        synchronized (mouseLock) {

            return mouseX;

        }

    }

    /**     * Returns the y-coordinate of the mouse.     *     * @return the y-coordinate of the mouse     */

    public double mouseY() {

        synchronized (mouseLock) {

            return mouseY;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseEntered(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseExited(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mousePressed(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

            isMousePressed = true;

        }

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mousePressed(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseReleased(MouseEvent e) {

        synchronized (mouseLock) {

            isMousePressed = false;

        }

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mouseReleased(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseClicked(MouseEvent e) {

        if (e.getButton() == MouseEvent.BUTTON1) {

            for (DrawListener listener : listeners)

                listener.mouseClicked(userX(e.getX()), userY(e.getY()));

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseDragged(MouseEvent e)  {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

        }

        // doesn’t seem to work if a button is specified        for (DrawListener listener : listeners)

            listener.mouseDragged(userX(e.getX()), userY(e.getY()));

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseMoved(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = userX(e.getX());

            mouseY = userY(e.getY());

        }

    }

   /***************************************************************************    *  Keyboard interactions.    ***************************************************************************/

    /**     * Returns true if the user has typed a key.     *     * @return {@code true} if the user has typed a key; {@code false} otherwise     */

    public boolean hasNextKeyTyped() {

        synchronized (keyLock) {

            return !keysTyped.isEmpty();

        }

    }

    /**     * The next key typed by the user.     *     * @return the next key typed by the user     */

    public char nextKeyTyped() {

        synchronized (keyLock) {

            return keysTyped.removeLast();

        }

    }

   /**     * Returns true if the keycode is being pressed.     * 

     * This method takes as an argument the keycode (corresponding to a physical key).     * It can handle action keys (such as F1 and arrow keys) and modifier keys     * (such as shift and control).     * See {@link KeyEvent} for a description of key codes.     *     * @param  keycode the keycode to check     * @return {@code true} if {@code keycode} is currently being pressed;     *         {@code false} otherwise     */

    public boolean isKeyPressed(int keycode) {

        synchronized (keyLock) {

            return keysDown.contains(keycode);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyTyped(KeyEvent e) {

        synchronized (keyLock) {

            keysTyped.addFirst(e.getKeyChar());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyTyped(e.getKeyChar());

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyPressed(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.add(e.getKeyCode());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyPressed(e.getKeyCode());

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyReleased(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.remove(e.getKeyCode());

        }

        // notify all listeners        for (DrawListener listener : listeners)

            listener.keyPressed(e.getKeyCode());

    }

   /***************************************************************************    *  For improved resolution on Mac Retina displays.    ***************************************************************************/

    private static class RetinaImageIcon extends ImageIcon {

            public RetinaImageIcon(Image image) {

            super(image);

        }

        public int getIconWidth() {

            return super.getIconWidth() / 2;

        }

        /**         * Gets the height of the icon.         *         * @return the height in pixels of this icon         */

        public int getIconHeight() {

            return super.getIconHeight() / 2;

        }

        public synchronized void paintIcon(Component c, Graphics g, int x, int y) {

            Graphics2D g2 = (Graphics2D) g.create();

            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);

            g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

            g2.scale(0.5, 0.5);

            super.paintIcon(c, g2, x * 2, y * 2);

            g2.dispose();

        }

    }

    /**     * Test client.     *     * @param args the command-line arguments     */

    public static void main(String[] args) {

        // create one drawing window        Draw draw1 = new Draw(“Test client 1”);

        draw1.square(0.2, 0.8, 0.1);

        draw1.filledSquare(0.8, 0.8, 0.2);

        draw1.circle(0.8, 0.2, 0.2);

        draw1.setPenColor(Draw.MAGENTA);

        draw1.setPenRadius(0.02);

        draw1.arc(0.8, 0.2, 0.1, 200, 45);

        // create another one        Draw draw2 = new Draw(“Test client 2”);

        draw2.setCanvasSize(900, 200);

        // draw a blue diamond        draw2.setPenRadius();

        draw2.setPenColor(Draw.BLUE);

        double[] x = { 0.1, 0.2, 0.3, 0.2 };

        double[] y = { 0.2, 0.3, 0.2, 0.1 };

        draw2.filledPolygon(x, y);

        // text        draw2.setPenColor(Draw.BLACK);

        draw2.text(0.2, 0.5, “bdfdfdfdlack text”);

        draw2.setPenColor(Draw.WHITE);

        draw2.text(0.8, 0.8, “white text”);

    }

}

DrawListener.java
DrawListener.java
/******************************************************************************

 *  Compilation:  javac DrawListener.java

 *  Execution:    none

 *  Dependencies: none

 *

 *  Interface that accompanies Draw.java.

 ******************************************************************************/

/**

 *  DrawListener. This interface provides a basic capability for

 *  responding to keyboard in mouse events from {
@link
 Draw} via callbacks.

 *  You can see some examples in

 *  Section 3.6.

 *

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
interface
 
DrawListener
 
{

    
/**

     * Invoked when the mouse has been pressed.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mousePressed
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been dragged.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseDragged
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been released.

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseReleased
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when the mouse has been clicked (pressed and released).

     *

     * 
@param
 x the x-coordinate of the mouse

     * 
@param
 y the y-coordinate of the mouse

     */

    
void
 mouseClicked
(
double
 x
,
 
double
 y
);

    
/**

     * Invoked when a key has been typed.

     *

     * 
@param
 c the character typed

     */

    
void
 keyTyped
(
char
 c
);

    
/**

     * Invoked when a key has been pressed.

     *

     * 
@param
 keycode the key combination pressed

     */

    
void
 keyPressed
(
int
 keycode
);

    
/**

     * Invoked when a key has been released.

     *

     * 
@param
 keycode the key combination released

     */

    
void
 keyReleased
(
int
 keycode
);

}

GrayscalePicture.java
GrayscalePicture.java
/******************************************************************************

 *  Compilation:  javac GrayscalePicture.java

 *  Execution:    java GrayscalePicture imagename

 *  Dependencies: none

 *

 *  Data type for manipulating individual pixels of a grayscale image. The

 *  original image can be read from a file in JPEG, GIF, or PNG format, or the

 *  user can create a blank image of a given dimension. Includes methods for

 *  displaying the image in a window on the screen or saving to a file.

 *

 *  % java GrayscalePicture mandrill

 *

 *  Remarks

 *  ——-

 *   – pixel (x, y) is column x and row y, where (0, 0) is upper left

 *

 *   – uses BufferedImage.TYPE_INT_RGB because BufferedImage.TYPE_BYTE_GRAY

 *     seems to do some undesirable olor correction when calling getRGB() and

 *     setRGB()

 *

 ******************************************************************************/

import
 java
.
awt
.
Color
;

import
 java
.
awt
.
FileDialog
;

import
 java
.
awt
.
Toolkit
;

import
 java
.
awt
.
event
.
ActionEvent
;

import
 java
.
awt
.
event
.
ActionListener
;

import
 java
.
awt
.
event
.
KeyEvent
;

import
 java
.
awt
.
image
.
BufferedImage
;

import
 java
.
io
.
File
;

import
 java
.
io
.
IOException
;

import
 java
.
net
.
URL
;

import
 javax
.
imageio
.
ImageIO
;

import
 javax
.
swing
.
ImageIcon
;

import
 javax
.
swing
.
JFrame
;

import
 javax
.
swing
.
JLabel
;

import
 javax
.
swing
.
JMenu
;

import
 javax
.
swing
.
JMenuBar
;

import
 javax
.
swing
.
JMenuItem
;

import
 javax
.
swing
.
JPanel
;

import
 javax
.
swing
.
KeyStroke
;

/**

 *  This class provides methods for manipulating individual pixels of

 *  a grayscale image.

 *  The original image can be read from a {
@code
 PNG}, {
@code
 GIF},

 *  or {
@code
 JPEG} file or the user can create a blank image of a given dimension.

 *  This class includes methods for displaying the image in a window on

 *  the screen or saving it to a file.

 *  

 *  Pixel (colrow) is column col and row row.

 *  By default, the origin (0, 0) is the pixel in the top-left corner,

 *  which is a common convention in image processing.

 *  The method {
@link
 #setOriginLowerLeft()} change the origin to the lower left.

 *  

 *  The {
@code
 get()} and {
@code
 set()} methods use {
@link
 Color} objects to get

 *  or set the color of the specified pixel. The {
@link
 Color} objects are converted

 *  to grayscale if they have different values for the R, G, and B channels.

 *  The {
@code
 getGrayscale()} and {
@code
 setGrayscale()} methods use an

 *  8-bit {
@code
 int} to encode the grayscale value, thereby avoiding the need to

 *  create temporary {
@code
 Color} objects.

 *  

 *  A W-by-H picture uses ~ 4 W H bytes of memory,

 *  since the color of each pixel is encoded as a 32-bit int

 *  (even though, in principle, only ~ W H bytes are needed).

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *  See {
@link
 Picture} for a version that supports 32-bit RGB color images.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
GrayscalePicture
 
implements
 
ActionListener
 
{

    
private
 
BufferedImage
 image
;
               
// the rasterized image

    
private
 
JFrame
 frame
;
                      
// on-screen view

    
private
 
String
 filename
;
                   
// name of file

    
private
 
boolean
 isOriginUpperLeft 
=
 
true
;
  
// location of origin

    
private
 
final
 
int
 width
,
 height
;
           
// width and height

   
/**

     * Creates a {
@code
 width}-by-{
@code
 height} picture, with {
@code
 width} columns

     * and {
@code
 height} rows, where each pixel is black.

     *

     * 
@param
 width the width of the picture

     * 
@param
 height the height of the picture

     * 
@throws
 IllegalArgumentException if {
@code
 width} is negative

     * 
@throws
 IllegalArgumentException if {
@code
 height} is negative

     */

    
public
 
GrayscalePicture
(
int
 width
,
 
int
 height
)
 
{

        
if
 
(
width  
<   0 )   throw   new   IllegalArgumentException ( "width must be non-negative" );          if   ( height  <   0 )   throw   new   IllegalArgumentException ( "height must be non-negative" );          this . width   =  width ;          this . height  =  height ;         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );      }     /**      * Creates a new grayscale picture that is a deep copy of the argument picture.      *      *  @param   picture the picture to copy      *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}      */      public   GrayscalePicture ( GrayscalePicture  picture )   {          if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );         width   =  picture . width ();         height  =  picture . height ();         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );         filename  =  picture . filename ;         isOriginUpperLeft  =  picture . isOriginUpperLeft ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                 image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));      }     /**      * Creates a grayscale picture by reading an image from a file or URL.      *      *  @param   name the name of the file ( , .gif, or  ) or URL.      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   GrayscalePicture ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          this . filename  =  name ;          try   {              // try to read from file in working directory              File  file  =   new   File ( name );              if   ( file . isFile ())   {                 image  =   ImageIO . read ( file );              }              else   {                  // resource relative to .class file                 URL url  =  getClass (). getResource ( name );                  // resource relative to classloader root                  if   ( url  ==   null )   {                     url  =  getClass (). getClassLoader (). getResource ( name );                  }                        // or URL from web                  if   ( url  ==   null )   {                     url  =   new  URL ( name );                  }                          image  =   ImageIO . read ( url );              }              if   ( image  ==   null )   {                  throw   new   IllegalArgumentException ( "could not read image: "   +  name );              }             width   =  image . getWidth ( null );             height  =  image . getHeight ( null );              // convert to grayscale inplace              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {                      Color  color  =   new   Color ( image . getRGB ( col ,  row ));                      Color  gray  =  toGray ( color );                     image . setRGB ( col ,  row ,  gray . getRGB ());                  }              }          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );          }      }       // Returns a grayscale version of the given color as a Color object.      private   static   Color  toGray ( Color  color )   {          int  r  =  color . getRed ();          int  g  =  color . getGreen ();          int  b  =  color . getBlue ();          int  y  =   ( int )   ( Math . round ( 0.299 * r  +   0.587 * g  +   0.114 * b ));          return   new   Color ( y ,  y ,  y );      }     /**      * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},      * { @link  JFrame} or other GUI widget.      *      *  @return  the { @code  JLabel}      */      public   JLabel  getJLabel ()   {          if   ( image  ==   null )   return   null ;           // no image available          ImageIcon  icon  =   new   ImageIcon ( image );          return   new   JLabel ( icon );      }     /**      * Sets the origin to be the upper left pixel. This is the default.      */      public   void  setOriginUpperLeft ()   {         isOriginUpperLeft  =   true ;      }     /**      * Sets the origin to be the lower left pixel.      */      public   void  setOriginLowerLeft ()   {         isOriginUpperLeft  =   false ;      }     /**      * Displays the picture in a window on the screen.      */      public   void  show ()   {          // create the GUI for viewing the image if needed          if   ( frame  ==   null )   {             frame  =   new   JFrame ();              JMenuBar  menuBar  =   new   JMenuBar ();              JMenu  menu  =   new   JMenu ( "File" );             menuBar . add ( menu );              JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );             menuItem1 . addActionListener ( this );              // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)             menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                       Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));             menu . add ( menuItem1 );             frame . setJMenuBar ( menuBar );             frame . setContentPane ( getJLabel ());              // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);             frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );              if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );              else                   frame . setTitle ( filename );             frame . setResizable ( false );             frame . pack ();             frame . setVisible ( true );          }          // draw         frame . repaint ();      }     /**      * Returns the height of the picture.      *      *  @return  the height of the picture (in pixels)      */      public   int  height ()   {          return  height ;      }     /**      * Returns the width of the picture.      *      *  @return  the width of the picture (in pixels)      */      public   int  width ()   {          return  width ;      }      private   void  validateRowIndex ( int  row )   {          if   ( row  <   0   ||  row  >=
 height
())

            
throw
 
new
 
IllegalArgumentException
(
“row index must be between 0 and ”
 
+
 
(
height
()
 

 
1
)
 
+
 
“: ”
 
+
 row
);

    
}

    
private
 
void
 validateColumnIndex
(
int
 col
)
 
{

        
if
 
(
col 
<   0   ||  col  >=
 width
())

            
throw
 
new
 
IllegalArgumentException
(
“column index must be between 0 and ”
 
+
 
(
width
()
 

 
1
)
 
+
 
“: ”
 
+
 col
);

    
}

    
private
 
void
 validateGrayscaleValue
(
int
 gray
)
 
{

        
if
 
(
gray 
<   0   ||  gray  >=
 
256
)

            
throw
 
new
 
IllegalArgumentException
(
“grayscale value must be between 0 and 255”
);

    
}

   
/**

     * Returns the grayscale value of pixel ({
@code
 col}, {
@code
 row}) as a {
@link
 java.awt.Color}.

     *

     * 
@param
 col the column index

     * 
@param
 row the row index

     * 
@return
 the grayscale value of pixel ({
@code
 col}, {
@code
 row})

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= col < width} and { @code  0 <= row < height}      */      public   Color  get ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          Color  color  =   new   Color ( image . getRGB ( col ,  row ));          return  toGray ( color );      }     /**      * Returns the grayscale value of pixel ({ @code  col}, { @code  row}) as an { @code  int}      * between 0 and 255.      * Using this method can be more efficient than { @link  #get(int, int)} because      * it does not create a { @code  Color} object.      *      *  @param  col the column index      *  @param  row the row index      *  @return  the 8-bit integer representation of the grayscale value of pixel ({ @code  col}, { @code  row})      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   int  getGrayscale ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row )   &   0xFF ;          else                     return  image . getRGB ( col ,  height  -  row  -   1 )   &   0xFF ;      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value.      *      *  @param  col the column index      *  @param  row the row index      *  @param  color the color (converts to grayscale if color is not a shade of gray)      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  set ( int  col ,   int  row ,   Color  color )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );          Color  gray  =  toGray ( color );         image . setRGB ( col ,  row ,  gray . getRGB ());      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value      * between 0 and 255.      *      *  @param  col the column index      *  @param  row the row index      *  @param  gray the 8-bit integer representation of the grayscale value      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   void  setGrayscale ( int  col ,   int  row ,   int  gray )   {         validateColumnIndex ( col );         validateRowIndex ( row );         validateGrayscaleValue ( gray );          int  rgb  =  gray  |   ( gray  <<   8 )   |   ( gray  <<   16 );          if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );          else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );      }     /**      * Returns true if this picture is equal to the argument picture.      *      *  @param  other the other picture      *  @return  { @code  true} if this picture is the same dimension as { @code  other}      *         and if all pixels have the same color; { @code  false} otherwise      */      public   boolean  equals ( Object  other )   {          if   ( other  ==   this )   return   true ;          if   ( other  ==   null )   return   false ;          if   ( other . getClass ()   !=   this . getClass ())   return   false ;          GrayscalePicture  that  =   ( GrayscalePicture )  other ;          if   ( this . width ()    !=  that . width ())    return   false ;          if   ( this . height ()   !=  that . height ())   return   false ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                  if   ( this . getGrayscale ( col ,  row )   !=  that . getGrayscale ( col ,  row ))   return   false ;          return   true ;      }     /**      * Returns a string representation of this picture.      * The result is a width-by-height matrix of pixels,

     * where the grayscale value of a pixel is an integer between 0 and 255.

     *

     * 
@return
 a string representation of this picture

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 sb 
=
 
new
 
StringBuilder
();

        sb
.
append
(
width 
+
“-by-”
 
+
 height 
+
 
” grayscale picture (grayscale values given in hex)\n”
);

        
for
 
(
int
 row 
=
 
0
;
 row 
<  height ;  row ++ )   {              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  int  gray  =   0 ;                  if   ( isOriginUpperLeft )  gray  =   0xFF   &  image . getRGB ( col ,  row );                  else                    gray  =   0xFF   &  image . getRGB ( col ,  height  -  row  -   1 );                 sb . append ( String . format ( "%3d " ,  gray ));              }             sb . append ( "\n" );          }          return  sb . toString (). trim ();      }      /**      * This operation is not supported because pictures are mutable.      *      *  @return  does not return a value      *  @throws  UnsupportedOperationException if called      */      public   int  hashCode ()   {          throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );      }     /**      * Saves the picture to a file in either PNG or JPEG format.      * The filetype extension must be either   or  .      *      *  @param  name the name of the file      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   void  save ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         save ( new   File ( name ));         filename  =  name ;      }     /**      * Saves the picture to a file in a PNG or JPEG image format.      *      *  @param   file the file      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   void  save ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         filename  =  file . getName ();          if   ( frame  !=   null )  frame . setTitle ( filename );          String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );          if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {              try   {                  ImageIO . write ( image ,  suffix ,  file );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }          }          else   {              System . out . println ( "Error: filename must end in   or  " );          }      }     /**      * Opens a save dialog box when the user selects "Save As" from the menu.      */     @ Override      public   void  actionPerformed ( ActionEvent  e )   {          FileDialog  chooser  =   new   FileDialog ( frame ,                               "Use a   or   extension" ,   FileDialog . SAVE );         chooser . setVisible ( true );          if   ( chooser . getFile ()   !=   null )   {             save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());          }      }     /**      * Unit tests this { @code  Picture} data type.      * Reads a picture specified by the command-line argument,      * and shows it in a window on the screen.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          GrayscalePicture  picture  =   new   GrayscalePicture ( args [ 0 ]);          StdOut . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());          GrayscalePicture  copy  =   new   GrayscalePicture ( picture );         picture . show ();         copy . show ();          while   ( ! StdIn . isEmpty ())   {              int  row  =   StdIn . readInt ();              int  col  =   StdIn . readInt ();              int  gray  =   StdIn . readInt ();             picture . setGrayscale ( row ,  col ,  gray );              StdOut . println ( picture . get ( row ,  col ));              StdOut . println ( picture . getGrayscale ( row ,  col ));          }      } } In.java In.java /******************************************************************************  *  Compilation:  javac In.java  *  Execution:    java In   (basic test --- see source for required files)  *  Dependencies: none  *  *  Reads in data of various types from standard input, files, and URLs.  *  ******************************************************************************/ import  java . io . BufferedInputStream ; import  java . io . File ; import  java . io . FileInputStream ; import  java . io . IOException ; import  java . io . InputStream ; import  java . net . URL ; import  java . net . Socket ; // import java.net.HttpURLConnection; import  java . net . URLConnection ; import  java . util . ArrayList ; import  java . util . InputMismatchException ; import  java . util . Locale ; import  java . util . NoSuchElementException ; import  java . util . Scanner ; import  java . util . regex . Pattern ; /**  *  Input. This class provides methods for reading strings

 *  and numbers from standard input, file input, URLs, and sockets. 

 *  

 *  The Locale used is: language = English, country = US. This is consistent

 *  with the formatting conventions with Java floating-point literals,

 *  command-line arguments (via {
@link
 Double#parseDouble(String)})

 *  and standard output. 

 *  

 *  For additional documentation, see 

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach 

 *  by Robert Sedgewick and Kevin Wayne.

 *  

 *  Like {
@link
 Scanner}, reading a token also consumes preceding Java

 *  whitespace, reading a full line consumes

 *  the following end-of-line delimeter, while reading a character consumes

 *  nothing extra. 

 *  

 *  Whitespace is defined in {
@link
 Character#isWhitespace(char)}. Newlines

 *  consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;

 *  see 

 *  Scanner.java (NB: Java 6u23 and earlier uses only \r, \r, \r\n).

 *

 *  
@author
 David Pritchard

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
In
 
{

    

    
///// begin: section (1 of 2) of code duplicated from In to StdIn.

    

    
// assume Unicode UTF-8 encoding

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with System.out.

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// the default token separator; we maintain the invariant that this value 

    
// is held by the scanner’s delimiter between calls

    
private
 
static
 
final
 
Pattern
 WHITESPACE_PATTERN 
=
 
Pattern
.
compile
(
“\\p{javaWhitespace}+”
);

    
// makes whitespace characters significant 

    
private
 
static
 
final
 
Pattern
 EMPTY_PATTERN 
=
 
Pattern
.
compile
(
“”
);

    
// used to read the entire input. source:

    
// http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html

    
private
 
static
 
final
 
Pattern
 EVERYTHING_PATTERN 
=
 
Pattern
.
compile
(
“\\A”
);

    
//// end: section (1 of 2) of code duplicated from In to StdIn.

    
private
 
Scanner
 scanner
;

   
/**

     * Initializes an input stream from standard input.

     */

    
public
 
In
()
 
{

        scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
System
.
in
),
 CHARSET_NAME
);

        scanner
.
useLocale
(
LOCALE
);

    
}

   
/**

     * Initializes an input stream from a socket.

     *

     * 
@param
  socket the socket

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 socket}

     * 
@throws
 IllegalArgumentException if {
@code
 socket} is {
@code
 null}

     */

    
public
 
In
(
Socket
 socket
)
 
{

        
if
 
(
socket 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“socket argument is null”
);

        
try
 
{

            
InputStream
 is 
=
 socket
.
getInputStream
();

            scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 socket
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a URL.

     *

     * 
@param
  url the URL

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 url}

     * 
@throws
 IllegalArgumentException if {
@code
 url} is {
@code
 null}

     */

    
public
 
In
(
URL url
)
 
{

        
if
 
(
url 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“url argument is null”
);

        
try
 
{

            
URLConnection
 site 
=
 url
.
openConnection
();

            
InputStream
 is     
=
 site
.
getInputStream
();

            scanner            
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 url
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a file.

     *

     * 
@param
  file the file

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 file}

     * 
@throws
 IllegalArgumentException if {
@code
 file} is {
@code
 null}

     */

    
public
 
In
(
File
 file
)
 
{

        
if
 
(
file 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“file argument is null”
);

        
try
 
{

            
// for consistency with StdIn, wrap with BufferedInputStream instead of use

            
// file as argument to Scanner

            
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

            scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
fis
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 file
,
 ioe
);

        
}

    
}

   
/**

     * Initializes an input stream from a filename or web page name.

     *

     * 
@param
  name the filename or web page name

     * 
@throws
 IllegalArgumentException if cannot open {
@code
 name} as

     *         a file or URL

     * 
@throws
 IllegalArgumentException if {
@code
 name} is {
@code
 null}

     */

    
public
 
In
(
String
 name
)
 
{

        
if
 
(
name 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument is null”
);

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
name
);

            
if
 
(
file
.
exists
())
 
{

                
// for consistency with StdIn, wrap with BufferedInputStream instead of use

                
// file as argument to Scanner

                
FileInputStream
 fis 
=
 
new
 
FileInputStream
(
file
);

                scanner 
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
fis
),
 CHARSET_NAME
);

                scanner
.
useLocale
(
LOCALE
);

                
return
;

            
}

            
// resource relative to .class file

            URL url 
=
 getClass
().
getResource
(
name
);

            
// resource relative to classloader root

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 getClass
().
getClassLoader
().
getResource
(
name
);

            
}

            
// or URL from web

            
if
 
(
url 
==
 
null
)
 
{

                url 
=
 
new
 URL
(
name
);

            
}

            
URLConnection
 site 
=
 url
.
openConnection
();

            
// in order to set User-Agent, replace above line with these two

            
// HttpURLConnection site = (HttpURLConnection) url.openConnection();

            
// site.addRequestProperty(“User-Agent”, “Mozilla/4.76”);

            
InputStream
 is     
=
 site
.
getInputStream
();

            scanner            
=
 
new
 
Scanner
(
new
 
BufferedInputStream
(
is
),
 CHARSET_NAME
);

            scanner
.
useLocale
(
LOCALE
);

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“Could not open ”
 
+
 name
,
 ioe
);

        
}

    
}

    
/**

     * Initializes an input stream from a given {
@link
 Scanner} source; use with 

     * {
@code
 new Scanner(String)} to read from a string.

     * 

     * Note that this does not create a defensive copy, so the

     * scanner will be mutated as you read on. 

     *

     * 
@param
  scanner the scanner

     * 
@throws
 IllegalArgumentException if {
@code
 scanner} is {
@code
 null}

     */

    
public
 
In
(
Scanner
 scanner
)
 
{

        
if
 
(
scanner 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“scanner argument is null”
);

        
this
.
scanner 
=
 scanner
;

    
}

    
/**

     * Returns true if this input stream exists.

     *

     * 
@return
 {
@code
 true} if this input stream exists; {
@code
 false} otherwise

     */

    
public
 
boolean
 exists
()
  
{

        
return
 scanner 
!=
 
null
;

    
}

    

    
////  begin: section (2 of 2) of code duplicated from In to StdIn,

    
////  with all methods changed from “public” to “public static”.

   
/**

     * Returns true if input stream is empty (except possibly whitespace).

     * Use this to know whether the next call to {
@link
 #readString()}, 

     * {
@link
 #readDouble()}, etc will succeed.

     *

     * 
@return
 {
@code
 true} if this input stream is empty (except possibly whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 isEmpty
()
 
{

        
return
 
!
scanner
.
hasNext
();

    
}

   
/** 

     * Returns true if this input stream has a next line.

     * Use this method to know whether the

     * next call to {
@link
 #readLine()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextChar()}.

     *

     * 
@return
 {
@code
 true} if this input stream has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
boolean
 hasNextLine
()
 
{

        
return
 scanner
.
hasNextLine
();

    
}

    
/**

     * Returns true if this input stream has more input (including whitespace).

     * Use this method to know whether the next call to {
@link
 #readChar()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextLine()}.

     * 

     * 
@return
 {
@code
 true} if this input stream has more input (including whitespace);

     *         {
@code
 false} otherwise   

     */

    
public
 
boolean
 hasNextChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
boolean
 result 
=
 scanner
.
hasNext
();

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

        
return
 result
;

    
}

   
/**

     * Reads and returns the next line in this input stream.

     *

     * 
@return
 the next line in this input stream; {
@code
 null} if no such line

     */

    
public
 
String
 readLine
()
 
{

        
String
 line
;

        
try
 
{

            line 
=
 scanner
.
nextLine
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            line 
=
 
null
;

        
}

        
return
 line
;

    
}

    
/**

     * Reads and returns the next character in this input stream.

     *

     * 
@return
 the next {
@code
 char} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     */

    
public
 
char
 readChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
try
 
{

            
String
 ch 
=
 scanner
.
next
();

            
assert
 ch
.
length
()
 
==
 
1
 
:
 
“Internal (Std)In.readChar() error!”

                
+
 
” Please contact the authors.”
;

            scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

            
return
 ch
.
charAt
(
0
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘char’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}
  

   
/**

     * Reads and returns the remainder of this input stream, as a string.

     *

     * 
@return
 the remainder of this input stream, as a string

     */

    
public
 
String
 readAll
()
 
{

        
if
 
(
!
scanner
.
hasNextLine
())

            
return
 
“”
;

        
String
 result 
=
 scanner
.
useDelimiter
(
EVERYTHING_PATTERN
).
next
();

        
// not that important to reset delimeter, since now scanner is empty

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);
 
// but let’s do it anyway

        
return
 result
;

    
}

   
/**

     * Reads the next token from this input stream and returns it as a {
@code
 String}.

     *

     * 
@return
 the next {
@code
 String} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     */

    
public
 
String
 readString
()
 
{

        
try
 
{

            
return
 scanner
.
next
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘String’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 int},

     * and returns the {
@code
 int}.

     *

     * 
@return
 the next {
@code
 int} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as an {
@code
 int}

     */

    
public
 
int
 readInt
()
 
{

        
try
 
{

            
return
 scanner
.
nextInt
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read an ‘int’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read an ‘int’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 double},

     * and returns the {
@code
 double}.

     *

     * 
@return
 the next {
@code
 double} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 double}

     */

    
public
 
double
 readDouble
()
 
{

        
try
 
{

            
return
 scanner
.
nextDouble
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘double’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘double’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 float},

     * and returns the {
@code
 float}.

     *

     * 
@return
 the next {
@code
 float} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 float}

     */

    
public
 
float
 readFloat
()
 
{

        
try
 
{

            
return
 scanner
.
nextFloat
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘float’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘float’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 long},

     * and returns the {
@code
 long}.

     *

     * 
@return
 the next {
@code
 long} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 long}

     */

    
public
 
long
 readLong
()
 
{

        
try
 
{

            
return
 scanner
.
nextLong
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘long’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘long’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 short},

     * and returns the {
@code
 short}.

     *

     * 
@return
 the next {
@code
 short} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 short}

     */

    
public
 
short
 readShort
()
 
{

        
try
 
{

            
return
 scanner
.
nextShort
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘short’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘short’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from this input stream, parses it as a {
@code
 byte},

     * and returns the {
@code
 byte}.

     * 

     * To read binary data, use {
@link
 BinaryIn}.

     *

     * 
@return
 the next {
@code
 byte} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 byte}

     */

    
public
 
byte
 readByte
()
 
{

        
try
 
{

            
return
 scanner
.
nextByte
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘byte’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read a ‘byte’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads the next token from this input stream, parses it as a {
@code
 boolean}

     * (interpreting either {
@code
 “true”} or {
@code
 “1”} as {
@code
 true},

     * and either {
@code
 “false”} or {
@code
 “0”} as {
@code
 false}).

     *

     * 
@return
 the next {
@code
 boolean} in this input stream

     * 
@throws
 NoSuchElementException if the input stream is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 boolean}

     */

    
public
 
boolean
 readBoolean
()
 
{

        
try
 
{

            
String
 token 
=
 readString
();

            
if
 
(
“true”
.
equalsIgnoreCase
(
token
))
  
return
 
true
;

            
if
 
(
“false”
.
equalsIgnoreCase
(
token
))
 
return
 
false
;

            
if
 
(
“1”
.
equals
(
token
))
               
return
 
true
;

            
if
 
(
“0”
.
equals
(
token
))
               
return
 
false
;

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘boolean’ value from the input stream, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘boolean’ value from the input stream, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads all remaining tokens from this input stream and returns them as

     * an array of strings.

     *

     * 
@return
 all remaining tokens in this input stream, as an array of strings

     */

    
public
 
String
[]
 readAllStrings
()
 
{

        
// we could use readAll.trim().split(), but that’s not consistent

        
// since trim() uses characters 0x00..0x20 as whitespace

        
String
[]
 tokens 
=
 WHITESPACE_PATTERN
.
split
(
readAll
());

        
if
 
(
tokens
.
length 
==
 
0
 
||
 tokens
[
0
].
length
()
 
>
 
0
)

            
return
 tokens
;

        
String
[]
 decapitokens 
=
 
new
 
String
[
tokens
.
length

1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  tokens . length - 1 ;  i ++ )             decapitokens [ i ]   =  tokens [ i + 1 ];          return  decapitokens ;      }      /**      * Reads all remaining lines from this input stream and returns them as      * an array of strings.      *      *  @return  all remaining lines in this input stream, as an array of strings      */      public   String []  readAllLines ()   {          ArrayList < String >
 lines 
=
 
new
 
ArrayList
< String >
();

        
while
 
(
hasNextLine
())
 
{

            lines
.
add
(
readLine
());

        
}

        
return
 lines
.
toArray
(
new
 
String
[
lines
.
size
()]);

    
}

    
/**

     * Reads all remaining tokens from this input stream, parses them as integers,

     * and returns them as an array of integers.

     *

     * 
@return
 all remaining lines in this input stream, as an array of integers

     */

    
public
 
int
[]
 readAllInts
()
 
{

        
String
[]
 fields 
=
 readAllStrings
();

        
int
[]
 vals 
=
 
new
 
int
[
fields
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  fields . length ;  i ++ )             vals [ i ]   =   Integer . parseInt ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from this input stream, parses them as longs,      * and returns them as an array of longs.      *      *  @return  all remaining lines in this input stream, as an array of longs      */      public   long []  readAllLongs ()   {          String []  fields  =  readAllStrings ();          long []  vals  =   new   long [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Long . parseLong ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from this input stream, parses them as doubles,      * and returns them as an array of doubles.      *      *  @return  all remaining lines in this input stream, as an array of doubles      */      public   double []  readAllDoubles ()   {          String []  fields  =  readAllStrings ();          double []  vals  =   new   double [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Double . parseDouble ( fields [ i ]);          return  vals ;      }           ///// end: section (2 of 2) of code duplicated from In to StdIn */     /**      * Closes this input stream.      */      public   void  close ()   {         scanner . close ();         }      /**      * Reads all integers from a file and returns them as      * an array of integers.      *      *  @param       filename the name of the file      *  @return      the integers in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ( String  filename )   {          return   new   In ( filename ). readAllInts ();      }     /**      * Reads all doubles from a file and returns them as      * an array of doubles.      *      *  @param       filename the name of the file      *  @return      the doubles in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ( String  filename )   {          return   new   In ( filename ). readAllDoubles ();      }     /**      * Reads all strings from a file and returns them as      * an array of strings.      *      *  @param       filename the name of the file      *  @return      the strings in the file      *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ( String  filename )   {          return   new   In ( filename ). readAllStrings ();      }      /**      * Reads all integers from standard input and returns them      * an array of integers.      *      *  @return      the integers on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ()   {          return   new   In (). readAllInts ();      }     /**      * Reads all doubles from standard input and returns them as      * an array of doubles.      *      *  @return      the doubles on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ()   {          return   new   In (). readAllDoubles ();      }     /**      * Reads all strings from standard input and returns them as      *  an array of strings.      *      *  @return      the strings on standard input      *  @deprecated  Replaced by { @link  StdIn#readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ()   {          return   new   In (). readAllStrings ();      }          /**      * Unit tests the { @code  In} data type.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          In  in ;          String  urlName  =   "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt" ;          // read from a URL          System . out . println ( "readAll() from URL "   +  urlName );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( urlName );              System . out . println ( in . readAll ());          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          // read one line at a time from URL          System . out . println ( "readLine() from URL "   +  urlName );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( urlName );              while   ( ! in . isEmpty ())   {                  String  s  =  in . readLine ();                  System . out . println ( s );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          // read one string at a time from URL          System . out . println ( "readString() from URL "   +  urlName );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( urlName );              while   ( ! in . isEmpty ())   {                  String  s  =  in . readString ();                  System . out . println ( s );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          // read one line at a time from file in current directory          System . out . println ( "readLine() from current directory" );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( "./InTest.txt" );              while   ( ! in . isEmpty ())   {                  String  s  =  in . readLine ();                  System . out . println ( s );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          // read one line at a time from file using relative path          System . out . println ( "readLine() from relative path" );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( "../stdlib/InTest.txt" );              while   ( ! in . isEmpty ())   {                  String  s  =  in . readLine ();                  System . out . println ( s );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          // read one char at a time          System . out . println ( "readChar() from file" );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( "InTest.txt" );              while   ( ! in . isEmpty ())   {                  char  c  =  in . readChar ();                  System . out . print ( c );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();          System . out . println ();          // read one line at a time from absolute OS X / Linux path          System . out . println ( "readLine() from absolute OS X / Linux path" );          System . out . println ( "---------------------------------------------------------------------------" );          try   {             in  =   new   In ( "/n/fs/introcs/www/java/stdlib/InTest.txt" );              while   ( ! in . isEmpty ())   {                  String  s  =  in . readLine ();                  System . out . println ( s );              }          }          catch   ( IllegalArgumentException  e )   {              System . out . println ( e );          }          System . out . println ();         // read one line at a time from absolute Windows path        System.out.println("readLine() from absolute Windows path");         System.out.println("---------------------------------------------------------------------------");         try {             in = new In("G:\\www\\introcs\\stdlib\\InTest.txt");             while (!in.isEmpty()) {                 String s = in.readLine();                 System.out.println(s);             }             System.out.println();         }         catch (IllegalArgumentException e) {             System.out.println(e);         }         System.out.println();     } } Out.java Out.java /******************************************************************************  *  Compilation:  javac Out.java  *  Execution:    java Out  *  Dependencies: none  *  *  Writes data of various types to: stdout, file, or socket.  *  ******************************************************************************/ import  java . io . FileOutputStream ; import  java . io . IOException ; import  java . io . OutputStream ; import  java . io . OutputStreamWriter ; import  java . io . PrintWriter ; import  java . net . Socket ; import  java . util . Locale ; /**  *  This class provides methods for writing strings and numbers to  *  various output streams, including standard output, file, and sockets.  *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Out
 
{

    
// force Unicode UTF-8 encoding; otherwise it’s system dependent

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with In

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
private
 
PrintWriter
 out
;

   
/**

     * Initializes an output stream from a {
@link
 OutputStream}.

     *

     * 
@param
  os the {
@code
 OutputStream}

     */

    
public
 
Out
(
OutputStream
 os
)
 
{

        
try
 
{

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes an output stream from standard output.

     */

    
public
 
Out
()
 
{

        
this
(
System
.
out
);

    
}

   
/**

     * Initializes an output stream from a socket.

     *

     * 
@param
  socket the socket

     */

    
public
 
Out
(
Socket
 socket
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 socket
.
getOutputStream
();

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Initializes an output stream from a file.

     *

     * 
@param
  filename the name of the file

     */

    
public
 
Out
(
String
 filename
)
 
{

        
try
 
{

            
OutputStream
 os 
=
 
new
 
FileOutputStream
(
filename
);

            
OutputStreamWriter
 osw 
=
 
new
 
OutputStreamWriter
(
os
,
 CHARSET_NAME
);

            out 
=
 
new
 
PrintWriter
(
osw
,
 
true
);

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

    
}

   
/**

     * Closes the output stream.

     */

    
public
 
void
 close
()
 
{

        out
.
close
();

    
}

   
/**

     * Terminates the current line by printing the line-separator string.

     */

    
public
 
void
 println
()
 
{

        out
.
println
();

    
}

   
/**

     * Prints an object to this output stream and then terminates the line.

     *

     * 
@param
 x the object to print

     */

    
public
 
void
 println
(
Object
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a boolean to this output stream and then terminates the line.

     *

     * 
@param
 x the boolean to print

     */

    
public
 
void
 println
(
boolean
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a character to this output stream and then terminates the line.

     *

     * 
@param
 x the character to print

     */

    
public
 
void
 println
(
char
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a double to this output stream and then terminates the line.

     *

     * 
@param
 x the double to print

     */

    
public
 
void
 println
(
double
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a float to this output stream and then terminates the line.

     *

     * 
@param
 x the float to print

     */

    
public
 
void
 println
(
float
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to this output stream and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
void
 println
(
int
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a long to this output stream and then terminates the line.

     *

     * 
@param
 x the long to print

     */

    
public
 
void
 println
(
long
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a byte to this output stream and then terminates the line.

     * 

     * To write binary data, see {
@link
 BinaryOut}.

     *

     * 
@param
 x the byte to print

     */

    
public
 
void
 println
(
byte
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Flushes this output stream.

     */

    
public
 
void
 print
()
 
{

        out
.
flush
();

    
}

   
/**

     * Prints an object to this output stream and flushes this output stream.

     * 

     * 
@param
 x the object to print

     */

    
public
 
void
 print
(
Object
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a boolean to this output stream and flushes this output stream.

     * 

     * 
@param
 x the boolean to print

     */

    
public
 
void
 print
(
boolean
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a character to this output stream and flushes this output stream.

     * 

     * 
@param
 x the character to print

     */

    
public
 
void
 print
(
char
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a double to this output stream and flushes this output stream.

     * 

     * 
@param
 x the double to print

     */

    
public
 
void
 print
(
double
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a float to this output stream and flushes this output stream.

     * 

     * 
@param
 x the float to print

     */

    
public
 
void
 print
(
float
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints an integer to this output stream and flushes this output stream.

     * 

     * 
@param
 x the integer to print

     */

    
public
 
void
 print
(
int
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a long integer to this output stream and flushes this output stream.

     * 

     * 
@param
 x the long integer to print

     */

    
public
 
void
 print
(
long
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a byte to this output stream and flushes this output stream.

     * 

     * 
@param
 x the byte to print

     */

    
public
 
void
 print
(
byte
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to this output stream, using the specified format

     * string and arguments, and then flushes this output stream.

     *

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
void
 printf
(
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
LOCALE
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to this output stream, using the specified

     * locale, format string, and arguments, and then flushes this output stream.

     *

     * 
@param
 locale the locale

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
void
 printf
(
Locale
 locale
,
 
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
locale
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * A test client.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
Out
 out
;

        
// write to stdout

        out 
=
 
new
 
Out
();

        out
.
println
(
“Test 1”
);

        out
.
close
();

        
// write to a file

        out 
=
 
new
 
Out
(
“test.txt”
);

        out
.
println
(
“Test 2”
);

        out
.
close
();

    
}

}

Picture.java
Picture.java
/******************************************************************************

 *  Compilation:  javac Picture.java

 *  Execution:    java Picture imagename

 *  Dependencies: none

 *

 *  Data type for manipulating individual pixels of an image. The original

 *  image can be read from a file in JPG, GIF, or PNG format, or the

 *  user can create a blank image of a given dimension. Includes methods for

 *  displaying the image in a window on the screen or saving to a file.

 *

 *  % java Picture mandrill

 *

 *  Remarks

 *  ——-

 *   – pixel (x, y) is column x and row y, where (0, 0) is upper left

 *

 ******************************************************************************/

import
 java
.
awt
.
Color
;

import
 java
.
awt
.
FileDialog
;

import
 java
.
awt
.
Toolkit
;

import
 java
.
awt
.
event
.
ActionEvent
;

import
 java
.
awt
.
event
.
ActionListener
;

import
 java
.
awt
.
event
.
KeyEvent
;

import
 java
.
awt
.
image
.
BufferedImage
;

import
 java
.
io
.
File
;

import
 java
.
io
.
IOException
;

import
 java
.
net
.
URL
;

import
 javax
.
imageio
.
ImageIO
;

import
 javax
.
swing
.
ImageIcon
;

import
 javax
.
swing
.
JFrame
;

import
 javax
.
swing
.
JLabel
;

import
 javax
.
swing
.
JMenu
;

import
 javax
.
swing
.
JMenuBar
;

import
 javax
.
swing
.
JMenuItem
;

import
 javax
.
swing
.
JPanel
;

import
 javax
.
swing
.
KeyStroke
;

/**

 *  This class provides methods for manipulating individual pixels of

 *  an image using the RGB color format. The alpha component (for transparency)

 *  is not currently supported.

 *  The original image can be read from a {
@code
 PNG}, {
@code
 GIF},

 *  or {
@code
 JPEG} file or the user can create a blank image of a given dimension.

 *  This class includes methods for displaying the image in a window on

 *  the screen or saving it to a file.

 *  

 *  Pixel (colrow) is column col and row row.

 *  By default, the origin (0, 0) is the pixel in the top-left corner,

 *  which is a common convention in image processing.

 *  The method {
@link
 #setOriginLowerLeft()} change the origin to the lower left.

 *  

 *  The {
@code
 get()} and {
@code
 set()} methods use {
@link
 Color} objects to get

 *  or set the color of the specified pixel.

 *  The {
@code
 getRGB()} and {
@code
 setRGB()} methods use a 32-bit {
@code
 int}

 *  to encode the color, thereby avoiding the need to create temporary

 *  {
@code
 Color} objects. The red (R), green (G), and blue (B) components 

 *  are encoded using the least significant 24 bits.

 *  Given a 32-bit {
@code
 int} encoding the color, the following code extracts

 *  the RGB components:

 * 


 *  int r = (rgb >> 16) & 0xFF;

 *  int g = (rgb >>  8) & 0xFF;

 *  int b = (rgb >>  0) & 0xFF;

 *  

 

 *  Given the RGB components (8-bits each) of a color,

 *  the following statement packs it into a 32-bit {
@code
 int}:

 * 


 *  int rgb = (r << 16) + (g << 8) + (b << 0);

 * 

 

 *  

 *  A W-by-H picture uses ~ 4 W H bytes of memory,

 *  since the color of each pixel is encoded as a 32-bit int.

 *  

 *  For additional documentation, see

 *  Section 3.1 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *  See {
@link
 GrayscalePicture} for a version that supports grayscale images.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
Picture
 
implements
 
ActionListener
 
{

    
private
 
BufferedImage
 image
;
               
// the rasterized image

    
private
 
JFrame
 frame
;
                      
// on-screen view

    
private
 
String
 filename
;
                   
// name of file

    
private
 
boolean
 isOriginUpperLeft 
=
 
true
;
  
// location of origin

    
private
 
final
 
int
 width
,
 height
;
           
// width and height

   
/**

     * Creates a {
@code
 width}-by-{
@code
 height} picture, with {
@code
 width} columns

     * and {
@code
 height} rows, where each pixel is black.

     *

     * 
@param
 width the width of the picture

     * 
@param
 height the height of the picture

     * 
@throws
 IllegalArgumentException if {
@code
 width} is negative or zero

     * 
@throws
 IllegalArgumentException if {
@code
 height} is negative or zero

     */

    
public
 
Picture
(
int
 width
,
 
int
 height
)
 
{

        
if
 
(
width  
<=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );          if   ( height  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );          this . width   =  width ;          this . height  =  height ;         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );          // set to TYPE_INT_ARGB here and in next constructor to support transparency      }     /**      * Creates a new picture that is a deep copy of the argument picture.      *      *  @param   picture the picture to copy      *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}      */      public   Picture ( Picture  picture )   {          if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );         width   =  picture . width ();         height  =  picture . height ();         image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );         filename  =  picture . filename ;         isOriginUpperLeft  =  picture . isOriginUpperLeft ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                 image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));      }     /**      * Creates a picture by reading an image from a file or URL.      *      *  @param   name the name of the file ( , .gif, or  ) or URL.      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   Picture ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          this . filename  =  name ;          try   {              // try to read from file in working directory              File  file  =   new   File ( name );              if   ( file . isFile ())   {                 image  =   ImageIO . read ( file );              }              else   {                  // resource relative to .class file                 URL url  =  getClass (). getResource ( filename );                  // resource relative to classloader root                  if   ( url  ==   null )   {                     url  =  getClass (). getClassLoader (). getResource ( name );                  }                  // or URL from web                  if   ( url  ==   null )   {                     url  =   new  URL ( name );                  }                 image  =   ImageIO . read ( url );              }              if   ( image  ==   null )   {                  throw   new   IllegalArgumentException ( "could not read image: "   +  name );              }             width   =  image . getWidth ( null );             height  =  image . getHeight ( null );          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );          }      }     /**      * Creates a picture by reading the image from a PNG, GIF, or JPEG file.      *      *  @param  file the file      *  @throws  IllegalArgumentException if cannot read image      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   Picture ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );          try   {             image  =   ImageIO . read ( file );          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not open file: "   +  file ,  ioe );          }          if   ( image  ==   null )   {              throw   new   IllegalArgumentException ( "could not read file: "   +  file );          }         width   =  image . getWidth ( null );         height  =  image . getHeight ( null );         filename  =  file . getName ();      }     /**      * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},      * { @link  JFrame} or other GUI widget.      *      *  @return  the { @code  JLabel}      */      public   JLabel  getJLabel ()   {          if   ( image  ==   null )   return   null ;           // no image available          ImageIcon  icon  =   new   ImageIcon ( image );          return   new   JLabel ( icon );      }     /**      * Sets the origin to be the upper left pixel. This is the default.      */      public   void  setOriginUpperLeft ()   {         isOriginUpperLeft  =   true ;      }     /**      * Sets the origin to be the lower left pixel.      */      public   void  setOriginLowerLeft ()   {         isOriginUpperLeft  =   false ;      }     /**      * Displays the picture in a window on the screen.      */      public   void  show ()   {          // create the GUI for viewing the image if needed          if   ( frame  ==   null )   {             frame  =   new   JFrame ();              JMenuBar  menuBar  =   new   JMenuBar ();              JMenu  menu  =   new   JMenu ( "File" );             menuBar . add ( menu );              JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );             menuItem1 . addActionListener ( this );              // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)                        menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                       Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));             menu . add ( menuItem1 );             frame . setJMenuBar ( menuBar );             frame . setContentPane ( getJLabel ());              // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);             frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );              if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );              else                   frame . setTitle ( filename );             frame . setResizable ( false );             frame . pack ();             frame . setVisible ( true );          }          // draw         frame . repaint ();      }     /**      * Returns the height of the picture.      *      *  @return  the height of the picture (in pixels)      */      public   int  height ()   {          return  height ;      }     /**      * Returns the width of the picture.      *      *  @return  the width of the picture (in pixels)      */      public   int  width ()   {          return  width ;      }      private   void  validateRowIndex ( int  row )   {          if   ( row  <   0   ||  row  >=
 height
())

            
throw
 
new
 
IllegalArgumentException
(
“row index must be between 0 and ”
 
+
 
(
height
()
 

 
1
)
 
+
 
“: ”
 
+
 row
);

    
}

    
private
 
void
 validateColumnIndex
(
int
 col
)
 
{

        
if
 
(
col 
<   0   ||  col  >=
 width
())

            
throw
 
new
 
IllegalArgumentException
(
“column index must be between 0 and ”
 
+
 
(
width
()
 

 
1
)
 
+
 
“: ”
 
+
 col
);

    
}

   
/**

     * Returns the color of pixel ({
@code
 col}, {
@code
 row}) as a {
@link
 java.awt.Color}.

     *

     * 
@param
 col the column index

     * 
@param
 row the row index

     * 
@return
 the color of pixel ({
@code
 col}, {
@code
 row})

     * 
@throws
 IllegalArgumentException unless both {
@code
 0 <= col < width} and { @code  0 <= row < height}      */      public   Color  get ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          int  rgb  =  getRGB ( col ,  row );          return   new   Color ( rgb );      }     /**      * Returns the color of pixel ({ @code  col}, { @code  row}) as an { @code  int}.      * Using this method can be more efficient than { @link  #get(int, int)} because      * it does not create a { @code  Color} object.      *      *  @param  col the column index      *  @param  row the row index      *  @return  the integer representation of the color of pixel ({ @code  col}, { @code  row})      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   int  getRGB ( int  col ,   int  row )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row );          else                     return  image . getRGB ( col ,  height  -  row  -   1 );      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.      *      *  @param  col the column index      *  @param  row the row index      *  @param  color the color      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      *  @throws  IllegalArgumentException if { @code  color} is { @code  null}      */      public   void  set ( int  col ,   int  row ,   Color  color )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );          int  rgb  =  color . getRGB ();         setRGB ( col ,  row ,  rgb );      }     /**      * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.      *      *  @param  col the column index      *  @param  row the row index      *  @param  rgb the integer representation of the color      *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}      */      public   void  setRGB ( int  col ,   int  row ,   int  rgb )   {         validateColumnIndex ( col );         validateRowIndex ( row );          if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );          else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );      }     /**      * Returns true if this picture is equal to the argument picture.      *      *  @param  other the other picture      *  @return  { @code  true} if this picture is the same dimension as { @code  other}      *         and if all pixels have the same color; { @code  false} otherwise      */      public   boolean  equals ( Object  other )   {          if   ( other  ==   this )   return   true ;          if   ( other  ==   null )   return   false ;          if   ( other . getClass ()   !=   this . getClass ())   return   false ;          Picture  that  =   ( Picture )  other ;          if   ( this . width ()    !=  that . width ())    return   false ;          if   ( this . height ()   !=  that . height ())   return   false ;          for   ( int  col  =   0 ;  col  <  width ();  col ++ )              for   ( int  row  =   0 ;  row  <  height ();  row ++ )                  if   ( this . getRGB ( col ,  row )   !=  that . getRGB ( col ,  row ))   return   false ;          return   true ;      }     /**      * Returns a string representation of this picture.      * The result is a width-by-height matrix of pixels,

     * where the color of a pixel is represented using 6 hex digits to encode

     * the red, green, and blue components.

     *

     * 
@return
 a string representation of this picture

     */

    
public
 
String
 toString
()
 
{

        
StringBuilder
 sb 
=
 
new
 
StringBuilder
();

        sb
.
append
(
width 
+
“-by-”
 
+
 height 
+
 
” picture (RGB values given in hex)\n”
);

        
for
 
(
int
 row 
=
 
0
;
 row 
<  height ;  row ++ )   {              for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {                  int  rgb  =   0 ;                  if   ( isOriginUpperLeft )  rgb  =  image . getRGB ( col ,  row );                  else                    rgb  =  image . getRGB ( col ,  height  -  row  -   1 );                 sb . append ( String . format ( "#%06X " ,  rgb  &   0xFFFFFF ));              }             sb . append ( "\n" );          }          return  sb . toString (). trim ();      }      /**      * This operation is not supported because pictures are mutable.      *      *  @return  does not return a value      *  @throws  UnsupportedOperationException if called      */      public   int  hashCode ()   {          throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );      }     /**      * Saves the picture to a file in either PNG or JPEG format.      * The filetype extension must be either   or  .      *      *  @param  name the name of the file      *  @throws  IllegalArgumentException if { @code  name} is { @code  null}      */      public   void  save ( String  name )   {          if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         save ( new   File ( name ));         filename  =  name ;      }     /**      * Saves the picture to a file in a PNG or JPEG image format.      *      *  @param   file the file      *  @throws  IllegalArgumentException if { @code  file} is { @code  null}      */      public   void  save ( File  file )   {          if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );         filename  =  file . getName ();          if   ( frame  !=   null )  frame . setTitle ( filename );          String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );          if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {              try   {                  ImageIO . write ( image ,  suffix ,  file );              }              catch   ( IOException  e )   {                 e . printStackTrace ();              }          }          else   {              System . out . println ( "Error: filename must end in   or  " );          }      }     /**      * Opens a save dialog box when the user selects "Save As" from the menu.      */     @ Override      public   void  actionPerformed ( ActionEvent  e )   {          FileDialog  chooser  =   new   FileDialog ( frame ,                               "Use a   or   extension" ,   FileDialog . SAVE );         chooser . setVisible ( true );          if   ( chooser . getFile ()   !=   null )   {             save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());          }      }     /**      * Unit tests this { @code  Picture} data type.      * Reads a picture specified by the command-line argument,      * and shows it in a window on the screen.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          Picture  picture  =   new   Picture ( args [ 0 ]);          System . out . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());         picture . show ();      } } PlayMusic.java PlayMusic.java import  java . io . InputStream ; import  java . io . IOException ; import  java . applet . * ; import  java . net . * ; import  java . io . * ; import  javax . sound . sampled . AudioFormat ; import  javax . sound . sampled . AudioInputStream ; import  javax . sound . sampled . AudioSystem ; import  javax . sound . sampled . DataLine ; import  javax . sound . sampled . LineUnavailableException ; import  javax . sound . sampled . SourceDataLine ; import  javax . sound . sampled . UnsupportedAudioFileException ; public   class   PlayMusic   {      // play sound file using Applet.newAudioClip();      private   static   void  playApplet ( String  filename )   {         URL url  =   null ;          try   {              File  file  =   new   File ( filename );              if   ( file . canRead ())  url  =  file . toURI (). toURL ();          }          catch   ( MalformedURLException  e )   {  e . printStackTrace ();   }          // URL url = StdAudio.class.getResource(filename);          if   ( url  ==   null )   throw   new   RuntimeException ( "audio "   +  filename  +   " not found" );          AudioClip  clip  =   Applet . newAudioClip ( url );         clip . play ();      }      public   static   synchronized   void  play ( final   String  filename )   {          // code adapted from: http://stackoverflow.com/questions/26305/how-can-i-play-sound-in-java          try   {              System . out . println ( "trying AudioSystem.getClip()" );              // check if file format is supported              // (if not, will throw an UnsupportedAudioFileException)              InputStream  is  =   PlayMusic . class . getResourceAsStream ( filename );              AudioInputStream  ais  =   AudioSystem . getAudioInputStream ( is );              new   Thread ( new   Runnable ()   {                 @ Override                  public   void  run ()   {                     stream ( filename );                  }              }). start ();          }          // let's try Applet.newAudioClip() instead          catch   ( UnsupportedAudioFileException  e )   {              System . out . println ( "trying Applet.newAudioClip()" );             playApplet ( filename );              System . out . println ( "done 2" );              return ;          }          // something else went wrong          catch   ( Exception  e )   {              System . out . println ( e );              System . out . println ( "Could not play "   +  filename );          }      }      // https://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html      // play a wav or aif file      // javax.sound.sampled.Clip fails for long clips (on some systems)      private   static   void  stream ( String  filename )   {          SourceDataLine  line  =   null ; //        int BUFFER_SIZE = 65526; // 64K buffer          int  BUFFER_SIZE  =   4096 ;   // 4K buffer          try   {              InputStream  is  =   PlayMusic . class . getResourceAsStream ( filename );              AudioInputStream  ais  =   AudioSystem . getAudioInputStream ( is );              AudioFormat  audioFormat  =  ais . getFormat ();              DataLine . Info  info  =   new   DataLine . Info ( SourceDataLine . class ,  audioFormat );             line  =   ( SourceDataLine )   AudioSystem . getLine ( info );             line . open ( audioFormat );             line . start ();              byte []  samples  =   new   byte [ BUFFER_SIZE ];              int  count  =   0 ;              while   (( count  =  ais . read ( samples ,   0 ,  BUFFER_SIZE ))   !=   - 1 )   {                 line . write ( samples ,   0 ,  count );              }          }          catch   ( IOException  e )   {             e . printStackTrace ();          }          catch   ( UnsupportedAudioFileException  e )   {             e . printStackTrace ();          }          catch   ( LineUnavailableException  e )   {             e . printStackTrace ();          }          finally   {              if   ( line  !=   null )   {                 line . drain ();                 line . close ();              }          }      }      public   static   void  main ( String []  args )   {          String  filename  =  args [ 0 ];         play ( filename );          System . out . println ( "done" );      } } StdArrayIO.java StdArrayIO.java /******************************************************************************  *  Compilation:  javac StdArrayIO.java  *  Execution:    java StdArrayIO < input.txt  *  Dependencies: StdOut.java  *  Data files:    https://introcs.cs.princeton.edu/java/22library/tinyDouble1D.txt  *                 https://introcs.cs.princeton.edu/java/22library/tinyDouble2D.txt  *                 https://introcs.cs.princeton.edu/java/22library/tinyBoolean2D.txt  *  *  A library for reading in 1D and 2D arrays of integers, doubles,  *  and booleans from standard input and printing them out to  *  standard output.  *  *  % more tinyDouble1D.txt   *  4  *    .000  .246  .222  -.032  *  *  % more tinyDouble2D.txt   *  4 3   *    .000  .270  .000   *    .246  .224 -.036   *    .222  .176  .0893   *   -.032  .739  .270   *  *  % more tinyBoolean2D.txt   *  4 3   *    1 1 0  *    0 0 0  *    0 1 1  *    1 1 1  *  *  % cat tinyDouble1D.txt tinyDouble2D.txt tinyBoolean2D.txt | java StdArrayIO  *  4  *    0.00000   0.24600   0.22200  -0.03200   *    *  4 3  *    0.00000   0.27000   0.00000   *    0.24600   0.22400  -0.03600   *    0.22200   0.17600   0.08930   *    0.03200   0.73900   0.27000   *  *  4 3  *  1 1 0   *  0 0 0   *  0 1 1   *  1 1 1   *  ******************************************************************************/ /**  *  Standard array IO. This class provides methods for reading

 *  in 1D and 2D arrays from standard input and printing out to 

 *  standard output.

 *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
StdArrayIO
 
{

    
// it doesn’t make sense to instantiate this class

    
private
 
StdArrayIO
()
 
{
 
}

    
/**

     * Reads a 1D array of doubles from standard input and returns it.

     *

     * 
@return
 the 1D array of doubles

     */

    
public
 
static
 
double
[]
 readDouble1D
()
 
{

        
int
 n 
=
 
StdIn
.
readInt
();

        
double
[]
 a 
=
 
new
 
double
[
n
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {             a [ i ]   =   StdIn . readDouble ();          }          return  a ;      }      /**      * Prints an array of doubles to standard output.      *      *  @param  a the 1D array of doubles      */      public   static   void  print ( double []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . printf ( "%9.5f " ,  a [ i ]);          }          StdOut . println ();      }               /**      * Reads a 2D array of doubles from standard input and returns it.      *      *  @return  the 2D array of doubles      */      public   static   double [][]  readDouble2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          double [][]  a  =   new   double [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readDouble ();              }          }          return  a ;      }      /**      * Prints the 2D array of doubles to standard output.      *      *  @param  a the 2D array of doubles      */      public   static   void  print ( double [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  StdOut . printf ( "%9.5f " ,  a [ i ][ j ]);              }              StdOut . println ();          }      }      /**      * Reads a 1D array of integers from standard input and returns it.      *      *  @return  the 1D array of integers      */      public   static   int []  readInt1D ()   {          int  n  =   StdIn . readInt ();          int []  a  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             a [ i ]   =   StdIn . readInt ();          }          return  a ;      }      /**      * Prints an array of integers to standard output.      *      *  @param  a the 1D array of integers      */      public   static   void  print ( int []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              StdOut . printf ( "%9d " ,  a [ i ]);          }          StdOut . println ();      }               /**      * Reads a 2D array of integers from standard input and returns it.      *      *  @return  the 2D array of integers      */      public   static   int [][]  readInt2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          int [][]  a  =   new   int [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readInt ();              }          }          return  a ;      }      /**      * Print a 2D array of integers to standard output.      *      *  @param  a the 2D array of integers      */      public   static   void  print ( int [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  StdOut . printf ( "%9d " ,  a [ i ][ j ]);              }              StdOut . println ();          }      }      /**      * Reads a 1D array of booleans from standard input and returns it.      *      *  @return  the 1D array of booleans      */      public   static   boolean []  readBoolean1D ()   {          int  n  =   StdIn . readInt ();          boolean []  a  =   new   boolean [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {             a [ i ]   =   StdIn . readBoolean ();          }          return  a ;      }      /**      * Prints a 1D array of booleans to standard output.      *      *  @param  a the 1D array of booleans      */      public   static   void  print ( boolean []  a )   {          int  n  =  a . length ;          StdOut . println ( n );          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              if   ( a [ i ])   StdOut . print ( "1 " );              else        StdOut . print ( "0 " );          }          StdOut . println ();      }      /**      * Reads a 2D array of booleans from standard input and returns it.      *      *  @return  the 2D array of booleans      */      public   static   boolean [][]  readBoolean2D ()   {          int  m  =   StdIn . readInt ();          int  n  =   StdIn . readInt ();          boolean [][]  a  =   new   boolean [ m ][ n ];          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                 a [ i ][ j ]   =   StdIn . readBoolean ();              }          }          return  a ;      }     /**      * Prints a 2D array of booleans to standard output.      *      *  @param  a the 2D array of booleans      */      public   static   void  print ( boolean [][]  a )   {          int  m  =  a . length ;          int  n  =  a [ 0 ]. length ;          StdOut . println ( m  +   " "   +  n );          for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {              for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {                  if   ( a [ i ][ j ])   StdOut . print ( "1 " );                  else           StdOut . print ( "0 " );              }              StdOut . println ();          }      }     /**      * Unit tests { @code  StdArrayIO}.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          // read and print an array of doubles          double []  a  =   StdArrayIO . readDouble1D ();          StdArrayIO . print ( a );          StdOut . println ();          // read and print a matrix of doubles          double [][]  b  =   StdArrayIO . readDouble2D ();          StdArrayIO . print ( b );          StdOut . println ();          // read and print a matrix of doubles          boolean [][]  d  =   StdArrayIO . readBoolean2D ();          StdArrayIO . print ( d );          StdOut . println ();      } } StdAudio.java StdAudio.java /******************************************************************************  *  Compilation:  javac StdAudio.java  *  Execution:    java StdAudio  *  Dependencies: none  *    *  Simple library for reading, writing, and manipulating .wav files.  *  *  *  Limitations  *  -----------  *    - Assumes the audio is monaural, little endian, with sampling rate  *      of 44,100  *    - check when reading .wav files from a .jar file ?  *  ******************************************************************************/ import  javax . sound . sampled . Clip ; import  java . io . File ; import  java . io . ByteArrayInputStream ; import  java . io . InputStream ; import  java . io . IOException ; import  java . net . URL ; import  javax . sound . sampled . AudioFileFormat ; import  javax . sound . sampled . AudioFormat ; import  javax . sound . sampled . AudioInputStream ; import  javax . sound . sampled . AudioSystem ; import  javax . sound . sampled . DataLine ; import  javax . sound . sampled . LineUnavailableException ; import  javax . sound . sampled . SourceDataLine ; import  javax . sound . sampled . UnsupportedAudioFileException ; import  javax . sound . sampled . LineListener ; import  javax . sound . sampled . LineEvent ; /**  *  Standard audio. This class provides a basic capability for

 *  creating, reading, and saving audio. 

 *  

 *  The audio format uses a sampling rate of 44,100 Hz, 16-bit, monaural.

 *

 *  

 *  For additional documentation, see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdAudio
 
{

    
/**

     *  The sample rate: 44,100 Hz for CD quality audio.

     */

    
public
 
static
 
final
 
int
 SAMPLE_RATE 
=
 
44100
;

    
private
 
static
 
final
 
int
 BYTES_PER_SAMPLE 
=
 
2
;
       
// 16-bit audio

    
private
 
static
 
final
 
int
 BITS_PER_SAMPLE 
=
 
16
;
       
// 16-bit audio

    
private
 
static
 
final
 
double
 MAX_16_BIT 
=
 
32768
;

    
private
 
static
 
final
 
int
 SAMPLE_BUFFER_SIZE 
=
 
4096
;

    
private
 
static
 
final
 
int
 MONO   
=
 
1
;

    
private
 
static
 
final
 
int
 STEREO 
=
 
2
;

    
private
 
static
 
final
 
boolean
 LITTLE_ENDIAN 
=
 
false
;

    
private
 
static
 
final
 
boolean
 BIG_ENDIAN    
=
 
true
;

    
private
 
static
 
final
 
boolean
 SIGNED        
=
 
true
;

    
private
 
static
 
final
 
boolean
 UNSIGNED      
=
 
false
;

    
private
 
static
 
SourceDataLine
 line
;
   
// to play the sound

    
private
 
static
 
byte
[]
 buffer
;
         
// our internal buffer

    
private
 
static
 
int
 bufferSize 
=
 
0
;
    
// number of samples currently in internal buffer

    
private
 
StdAudio
()
 
{

        
// can not instantiate

    
}

   

    
// static initializer

    
static
 
{

        init
();

    
}

    
// open up an audio stream

    
private
 
static
 
void
 init
()
 
{

        
try
 
{

            
// 44,100 Hz, 16-bit audio, mono, signed PCM, little endian

            
AudioFormat
 format 
=
 
new
 
AudioFormat
((
float
)
 SAMPLE_RATE
,
 BITS_PER_SAMPLE
,
 MONO
,
 SIGNED
,
 LITTLE_ENDIAN
);

            
DataLine
.
Info
 info 
=
 
new
 
DataLine
.
Info
(
SourceDataLine
.
class
,
 format
);

            line 
=
 
(
SourceDataLine
)
 
AudioSystem
.
getLine
(
info
);

            line
.
open
(
format
,
 SAMPLE_BUFFER_SIZE 
*
 BYTES_PER_SAMPLE
);

            

            
// the internal buffer is a fraction of the actual buffer size, this choice is arbitrary

            
// it gets divided because we can’t expect the buffered data to line up exactly with when

            
// the sound card decides to push out its samples.

            buffer 
=
 
new
 
byte
[
SAMPLE_BUFFER_SIZE 
*
 BYTES_PER_SAMPLE
/
3
];

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            
System
.
out
.
println
(
e
.
getMessage
());

        
}

        
// no sound gets made before this call

        line
.
start
();

    
}

    
// get an AudioInputStream object from a file

    
private
 
static
 
AudioInputStream
 getAudioInputStreamFromFile
(
String
 filename
)
 
{

        
if
 
(
filename 
==
 
null
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“filename is null”
);

        
}

        
try
 
{

            
// first try to read file from local file system

            
File
 file 
=
 
new
 
File
(
filename
);

            
if
 
(
file
.
exists
())
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
file
);

            
}

            
// resource relative to .class file

            
InputStream
 is1 
=
 
StdAudio
.
class
.
getResourceAsStream
(
filename
);

            
if
 
(
is1 
!=
 
null
)
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
is1
);

            
}

            
// resource relative to classloader root

            
InputStream
 is2 
=
 
StdAudio
.
class
.
getClassLoader
().
getResourceAsStream
(
filename
);

            
if
 
(
is2 
!=
 
null
)
 
{

                
return
 
AudioSystem
.
getAudioInputStream
(
is2
);

            
}

            
// give up

            
else
 
{

                
throw
 
new
 
IllegalArgumentException
(
“could not read ‘”
 
+
 filename 
+
 
“‘”
);

            
}

        
}

        
catch
 
(
IOException
 e
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“could not read ‘”
 
+
 filename 
+
 
“‘”
,
 e
);

        
}

        
catch
 
(
UnsupportedAudioFileException
 e
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“file of unsupported audio format: ‘”
 
+
 filename 
+
 
“‘”
,
 e
);

        
}

    
}

    
/**

     * Closes standard audio.

     */

    
public
 
static
 
void
 close
()
 
{

        line
.
drain
();

        line
.
stop
();

    
}

    

    
/**

     * Writes one sample (between -1.0 and +1.0) to standard audio.

     * If the sample is outside the range, it will be clipped.

     *

     * 
@param
  sample the sample to play

     * 
@throws
 IllegalArgumentException if the sample is {
@code
 Double.NaN}

     */

    
public
 
static
 
void
 play
(
double
 sample
)
 
{

        
if
 
(
Double
.
isNaN
(
sample
))
 
throw
 
new
 
IllegalArgumentException
(
“sample is NaN”
);

        
// clip if outside [-1, +1]

        
if
 
(
sample 
<   - 1.0 )  sample  =   - 1.0 ;          if   ( sample  >
 
+
1.0
)
 sample 
=
 
+
1.0
;

        
// convert to bytes

        
short
 s 
=
 
(
short
)
 
(
MAX_16_BIT 
*
 sample
);

        
if
 
(
sample 
==
 
1.0
)
 s 
=
 
Short
.
MAX_VALUE
;
   
// special case since 32768 not a short

        buffer
[
bufferSize
++
]
 
=
 
(
byte
)
 s
;

        buffer
[
bufferSize
++
]
 
=
 
(
byte
)
 
(

>>
 
8
);
   
// little endian

        
// send to sound card if buffer is full        

        
if
 
(
bufferSize 
>=
 buffer
.
length
)
 
{

            line
.
write
(
buffer
,
 
0
,
 buffer
.
length
);

            bufferSize 
=
 
0
;

        
}

    
}

    
/**

     * Writes the array of samples (between -1.0 and +1.0) to standard audio.

     * If a sample is outside the range, it will be clipped.

     *

     * 
@param
  samples the array of samples to play

     * 
@throws
 IllegalArgumentException if any sample is {
@code
 Double.NaN}

     * 
@throws
 IllegalArgumentException if {
@code
 samples} is {
@code
 null}

     */

    
public
 
static
 
void
 play
(
double
[]
 samples
)
 
{

        
if
 
(
samples 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument to play() is null”
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  samples . length ;  i ++ )   {             play ( samples [ i ]);          }      }      /**      * Reads audio samples from a file (in .wav or .au format) and returns      * them as a double array with values between -1.0 and +1.0.      * The audio file must be 16-bit with a sampling rate of 44,100.      * It can be mono or stereo.      *      *  @param   filename the name of the audio file      *  @return  the array of samples      */      public   static   double []  read ( String  filename )   {          // make sure that AudioFormat is 16-bit, 44,100 Hz, little endian          final   AudioInputStream  ais  =  getAudioInputStreamFromFile ( filename );          AudioFormat  audioFormat  =  ais . getFormat ();          // require sampling rate = 44,100 Hz          if   ( audioFormat . getSampleRate ()   !=  SAMPLE_RATE )   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only a sample rate of "   +  SAMPLE_RATE  +   " Hz\n"                                               +   "audio format: "   +  audioFormat );          }          // require 16-bit audio          if   ( audioFormat . getSampleSizeInBits ()   !=  BITS_PER_SAMPLE )   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only "   +  BITS_PER_SAMPLE  +   "-bit audio\n"                                               +   "audio format: "   +  audioFormat );          }          // require little endian          if   ( audioFormat . isBigEndian ())   {              throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only audio stored using little endian\n"                                               +   "audio format: "   +  audioFormat );          }          byte []  bytes  =   null ;          try   {              int  bytesToRead  =  ais . available ();             bytes  =   new   byte [ bytesToRead ];              int  bytesRead  =  ais . read ( bytes );              if   ( bytesToRead  !=  bytesRead )   {                  throw   new   IllegalStateException ( "read only "   +  bytesRead  +   " of "   +  bytesToRead  +   " bytes" );                }          }          catch   ( IOException  ioe )   {              throw   new   IllegalArgumentException ( "could not read '"   +  filename  +   "'" ,  ioe );          }          int  n  =  bytes . length ;          // little endian, mono          if   ( audioFormat . getChannels ()   ==  MONO )   {              double []  data  =   new   double [ n / 2 ];              for   ( int  i  =   0 ;  i  <  n / 2 ;  i ++ )   {                  // little endian, mono                 data [ i ]   =   (( short )   ((( bytes [ 2 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 2 * i ]   &   0xFF )))   /   (( double )  MAX_16_BIT );              }              return  data ;          }          // little endian, stereo          else   if   ( audioFormat . getChannels ()   ==  STEREO )   {              double []  data  =   new   double [ n / 4 ];              for   ( int  i  =   0 ;  i  <  n / 4 ;  i ++ )   {                  double  left   =   (( short )   ((( bytes [ 4 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * i  +   0 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );                  double  right  =   (( short )   ((( bytes [ 4 * i + 3 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * i  +   2 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );                 data [ i ]   =   ( left  +  right )   /   2.0 ;              }              return  data ;          }          // TODO: handle big endian (or other formats)          else   throw   new   IllegalStateException ( "audio format is neither mono or stereo" );      }      /**      * Saves the double array as an audio file (using .wav or .au format).      *      *  @param   filename the name of the audio file      *  @param   samples the array of samples      *  @throws  IllegalArgumentException if unable to save { @code  filename}      *  @throws  IllegalArgumentException if { @code  samples} is { @code  null}      *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}      *  @throws  IllegalArgumentException if { @code  filename} extension is not { @code  .wav}      *         or { @code  .au}      */      public   static   void  save ( String  filename ,   double []  samples )   {          if   ( filename  ==   null )   {              throw   new   IllegalArgumentException ( "filenameis null" );          }          if   ( samples  ==   null )   {              throw   new   IllegalArgumentException ( "samples[] is null" );          }          // assumes 16-bit samples with sample rate = 44,100 Hz          // use 16-bit audio, mono, signed PCM, little Endian          AudioFormat  format  =   new   AudioFormat ( SAMPLE_RATE ,   16 ,  MONO ,  SIGNED ,  LITTLE_ENDIAN );          byte []  data  =   new   byte [ 2   *  samples . length ];          for   ( int  i  =   0 ;  i  <  samples . length ;  i ++ )   {              int  temp  =   ( short )   ( samples [ i ]   *  MAX_16_BIT );              if   ( samples [ i ]   ==   1.0 )  temp  =   Short . MAX_VALUE ;     // special case since 32768 not a short             data [ 2 * i  +   0 ]   =   ( byte )  temp ;             data [ 2 * i  +   1 ]   =   ( byte )   ( temp  >>
 
8
);
   
// little endian

        
}

        
// now save the file

        
try
 
{

            
ByteArrayInputStream
 bais 
=
 
new
 
ByteArrayInputStream
(
data
);

            
AudioInputStream
 ais 
=
 
new
 
AudioInputStream
(
bais
,
 format
,
 samples
.
length
);

            
if
 
(
filename
.
endsWith
(
“.wav”
)
 
||
 filename
.
endsWith
(
“.WAV”
))
 
{

                
AudioSystem
.
write
(
ais
,
 
AudioFileFormat
.
Type
.
WAVE
,
 
new
 
File
(
filename
));

            
}

            
else
 
if
 
(
filename
.
endsWith
(
“.au”
)
 
||
 filename
.
endsWith
(
“.AU”
))
 
{

                
AudioSystem
.
write
(
ais
,
 
AudioFileFormat
.
Type
.
AU
,
 
new
 
File
(
filename
));

            
}

            
else
 
{

                
throw
 
new
 
IllegalArgumentException
(
“file type for saving must be .wav or .au”
);

            
}

        
}

        
catch
 
(
IOException
 ioe
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“unable to save file ‘”
 
+
 filename 
+
 
“‘”
,
 ioe
);

        
}

    
}

    
/**

     * Plays an audio file (in .wav, .mid, or .au format) in a background thread.

     *

     * 
@param
 filename the name of the audio file

     * 
@throws
 IllegalArgumentException if unable to play {
@code
 filename}

     * 
@throws
 IllegalArgumentException if {
@code
 filename} is {
@code
 null}

     */

    
public
 
static
 
synchronized
 
void
 play
(
final
 
String
 filename
)
 
{

        
new
 
Thread
(
new
 
Runnable
()
 
{

            
public
 
void
 run
()
 
{

                
AudioInputStream
 ais 
=
 getAudioInputStreamFromFile
(
filename
);

                stream
(
ais
);

            
}

        
}).
start
();

    
}

    
// https://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html

    
// play a wav or aif file

    
// javax.sound.sampled.Clip fails for long clips (on some systems), perhaps because

    
// JVM closes (see remedy in loop)

    
private
 
static
 
void
 stream
(
AudioInputStream
 ais
)
 
{

        
SourceDataLine
 line 
=
 
null
;

        
int
 BUFFER_SIZE 
=
 
4096
;
 
// 4K buffer

        
try
 
{

            
AudioFormat
 audioFormat 
=
 ais
.
getFormat
();

            
DataLine
.
Info
 info 
=
 
new
 
DataLine
.
Info
(
SourceDataLine
.
class
,
 audioFormat
);

            line 
=
 
(
SourceDataLine
)
 
AudioSystem
.
getLine
(
info
);

            line
.
open
(
audioFormat
);

            line
.
start
();

            
byte
[]
 samples 
=
 
new
 
byte
[
BUFFER_SIZE
];

            
int
 count 
=
 
0
;

            
while
 
((
count 
=
 ais
.
read
(
samples
,
 
0
,
 BUFFER_SIZE
))
 
!=
 

1
)
 
{

                line
.
write
(
samples
,
 
0
,
 count
);

            
}

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
finally
 
{

            
if
 
(
line 
!=
 
null
)
 
{

                line
.
drain
();

                line
.
close
();

            
}

        
}

    
}

    
/**

     * Loops an audio file (in .wav, .mid, or .au format) in a background thread.

     *

     * 
@param
 filename the name of the audio file

     * 
@throws
 IllegalArgumentException if {
@code
 filename} is {
@code
 null}

     */

    
public
 
static
 
synchronized
 
void
 loop
(
String
 filename
)
 
{

        
if
 
(
filename 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
();

        
final
 
AudioInputStream
 ais 
=
 getAudioInputStreamFromFile
(
filename
);

        
try
 
{

            
Clip
 clip 
=
 
AudioSystem
.
getClip
();

            
// Clip clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));

            clip
.
open
(
ais
);

            clip
.
loop
(
Clip
.
LOOP_CONTINUOUSLY
);

        
}

        
catch
 
(
LineUnavailableException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
catch
 
(
IOException
 e
)
 
{

            e
.
printStackTrace
();

        
}

        
// keep JVM open

        
new
 
Thread
(
new
 
Runnable
()
 
{

            
public
 
void
 run
()
 
{

                
while
 
(
true
)
 
{

                    
try
 
{

                       
Thread
.
sleep
(
1000
);

                    
}

                    
catch
 
(
InterruptedException
 e
)
 
{

                        e
.
printStackTrace
();

                    
}

                
}

            
}

        
}).
start
();

    
}

   
/***************************************************************************

    * Unit tests {
@code
 StdAudio}.

    ***************************************************************************/

    
// create a note (sine wave) of the given frequency (Hz), for the given

    
// duration (seconds) scaled to the given volume (amplitude)

    
private
 
static
 
double
[]
 note
(
double
 hz
,
 
double
 duration
,
 
double
 amplitude
)
 
{

        
int
 n 
=
 
(
int
)
 
(
StdAudio
.
SAMPLE_RATE 
*
 duration
);

        
double
[]
 a 
=
 
new
 
double
[
n
+
1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<=  n ;  i ++ )             a [ i ]   =  amplitude  *   Math . sin ( 2   *   Math . PI  *  i  *  hz  /   StdAudio . SAMPLE_RATE );          return  a ;      }      /**      * Test client - play an A major scale to standard audio.      *      *  @param  args the command-line arguments      */      /**      * Test client - play an A major scale to standard audio.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {                   // 440 Hz for 1 sec          double  freq  =   440.0 ;          for   ( int  i  =   0 ;  i  <=   StdAudio . SAMPLE_RATE ;  i ++ )   {              StdAudio . play ( 0.5   *   Math . sin ( 2 * Math . PI  *  freq  *  i  /   StdAudio . SAMPLE_RATE ));          }                   // scale increments          int []  steps  =   {   0 ,   2 ,   4 ,   5 ,   7 ,   9 ,   11 ,   12   };          for   ( int  i  =   0 ;  i  <  steps . length ;  i ++ )   {              double  hz  =   440.0   *   Math . pow ( 2 ,  steps [ i ]   /   12.0 );              StdAudio . play ( note ( hz ,   1.0 ,   0.5 ));          }          // need to call this in non-interactive stuff so the program doesn't terminate          // until all the sound leaves the speaker.          StdAudio . close ();        } } StdDraw.java StdDraw.java /******************************************************************************  *  Compilation:  javac StdDraw.java  *  Execution:    java StdDraw  *  Dependencies: none  *  *  Standard drawing library. This class provides a basic capability for  *  creating drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of points, lines, and curves  *  in a window on your computer and to save the drawings to a file.  *  *  Todo  *  ----  *    -  Add support for gradient fill, etc.  *    -  Fix setCanvasSize() so that it can only be called once.  *    -  On some systems, drawing a line (or other shape) that extends way  *       beyond canvas (e.g., to infinity) dimensions does not get drawn.  *  *  Remarks  *  -------  *    -  don't use AffineTransform for rescaling since it inverts  *       images and strings  *  ******************************************************************************/ import  java . awt . BasicStroke ; import  java . awt . Color ; import  java . awt . Component ; import  java . awt . FileDialog ; import  java . awt . Font ; import  java . awt . FontMetrics ; import  java . awt . Graphics ; import  java . awt . Graphics2D ; import  java . awt . Image ; import  java . awt . MediaTracker ; import  java . awt . RenderingHints ; import  java . awt . Toolkit ; import  java . awt . event . ActionEvent ; import  java . awt . event . ActionListener ; import  java . awt . event . MouseEvent ; import  java . awt . event . MouseListener ; import  java . awt . event . MouseMotionListener ; import  java . awt . event . KeyEvent ; import  java . awt . event . KeyListener ; import  java . awt . geom . Arc2D ; import  java . awt . geom . Ellipse2D ; import  java . awt . geom . GeneralPath ; import  java . awt . geom . Line2D ; import  java . awt . geom . Rectangle2D ; import  java . awt . image . BufferedImage ; import  java . awt . image . DirectColorModel ; import  java . awt . image . WritableRaster ; import  java . io . File ; import  java . io . IOException ; import  java . net . MalformedURLException ; import  java . net . URL ; import  java . util . LinkedList ; import  java . util . TreeSet ; import  java . util . NoSuchElementException ; import  javax . imageio . ImageIO ; import  javax . swing . ImageIcon ; import  javax . swing . JFrame ; import  javax . swing . JLabel ; import  javax . swing . JMenu ; import  javax . swing . JMenuBar ; import  javax . swing . JMenuItem ; import  javax . swing . KeyStroke ; /**  *  The { @code  StdDraw} class provides a basic capability for  *  creating drawings with your programs. It uses a simple graphics model that  *  allows you to create drawings consisting of points, lines, squares,   *  circles, and other geometric shapes in a window on your computer and  *  to save the drawings to a file. Standard drawing also includes  *  facilities for text, color, pictures, and animation, along with  *  user interaction via the keyboard and mouse.  *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdDraw.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdDraw.java

 *  and put a copy in your working directory.

 *  

 *  Now, type the following short program into your editor:

 *  


 *   public class TestStdDraw {

 *       public static void main(String[] args) {

 *           StdDraw.setPenRadius(0.05);

 *           StdDraw.setPenColor(StdDraw.BLUE);

 *           StdDraw.point(0.5, 0.5);

 *           StdDraw.setPenColor(StdDraw.MAGENTA);

 *           StdDraw.line(0.2, 0.2, 0.8, 0.2);

 *       }

 *   }

 *  

 *  If you compile and execute the program, you should see a window

 *  appear with a thick magenta line and a blue point.

 *  This program illustrates the two main types of methods in standard

 *  drawing—methods that draw geometric shapes and methods that

 *  control drawing parameters.

 *  The methods {
@code
 StdDraw.line()} and {
@code
 StdDraw.point()}

 *  draw lines and points; the methods {
@code
 StdDraw.setPenRadius()}

 *  and {
@code
 StdDraw.setPenColor()} control the line thickness and color.

 *  

 *  Points and lines.

 *  You can draw points and line segments with the following methods:

 *  

     *  

  •  {
    @link
     #point(double x, double y)}

     *  

  •  {
    @link
     #line(double x1, double y1, double x2, double y2)}

     *  

 *  

 *  The x– and y-coordinates must be in the drawing area

 *  (between 0 and 1 and by default) or the points and lines will not be visible.

 *  

 *  Squares, circles, rectangles, and ellipses.

 *  You can draw squares, circles, rectangles, and ellipses using

 *  the following methods:

 *  

     *  

  •  {
    @link
     #circle(double x, double y, double radius)}

     *  

  •  {
    @link
     #ellipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}

     *  

  •  {
    @link
     #square(double x, double y, double halfLength)}

     *  

  •  {
    @link
     #rectangle(double x, double y, double halfWidth, double halfHeight)}

     *  

 *  

 *  All of these methods take as arguments the location and size of the shape.

 *  The location is always specified by the x– and y-coordinates

 *  of its center.

 *  The size of a circle is specified by its radius and the size of an ellipse is

 *  specified by the lengths of its semi-major and semi-minor axes.

 *  The size of a square or rectangle is specified by its half-width or half-height.

 *  The convention for drawing squares and rectangles is parallel to those for

 *  drawing circles and ellipses, but may be unexpected to the uninitiated.

 *  

 *  The methods above trace outlines of the given shapes. The following methods

 *  draw filled versions:

 *  

     *  

  •  {
    @link
     #filledCircle(double x, double y, double radius)}

     *  

  •  {
    @link
     #filledEllipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}

     *  

  •  {
    @link
     #filledSquare(double x, double y, double radius)}

     *  

  •  {
    @link
     #filledRectangle(double x, double y, double halfWidth, double halfHeight)}

     *  

 *  

 *  Circular arcs.

 *  You can draw circular arcs with the following method:

 *  

     *  

  •  {
    @link
     #arc(double x, double y, double radius, double angle1, double angle2)}

     *  

 *  

 *  The arc is from the circle centered at (xy) of the specified radius.

 *  The arc extends from angle1 to angle2. By convention, the angles are

 *  polar (counterclockwise angle from the x-axis)

 *  and represented in degrees. For example, {
@code
 StdDraw.arc(0.0, 0.0, 1.0, 0, 90)}

 *  draws the arc of the unit circle from 3 o’clock (0 degrees) to 12 o’clock (90 degrees).

 *  

 *  Polygons.

 *  You can draw polygons with the following methods:

 *  

     *  

  •  {
    @link
     #polygon(double[] x, double[] y)}

     *  

  •  {
    @link
     #filledPolygon(double[] x, double[] y)}

     *  

 *  

 *  The points in the polygon are ({
@code
 x[i]}, {
@code
 y[i]}).

 *  For example, the following code fragment draws a filled diamond

 *  with vertices (0.1, 0.2), (0.2, 0.3), (0.3, 0.2), and (0.2, 0.1):

 *  


 *   double[] x = { 0.1, 0.2, 0.3, 0.2 };

 *   double[] y = { 0.2, 0.3, 0.2, 0.1 };

 *   StdDraw.filledPolygon(x, y);

 *  

 *  

 *  Pen size.

 *  The pen is circular, so that when you set the pen radius to r

 *  and draw a point, you get a circle of radius r. Also, lines are

 *  of thickness 2r and have rounded ends. The default pen radius

 *  is 0.005 and is not affected by coordinate scaling. This default pen

 *  radius is about 1/200 the width of the default canvas, so that if

 *  you draw 100 points equally spaced along a horizontal or vertical line,

 *  you will be able to see individual circles, but if you draw 200 such

 *  points, the result will look like a line.

 *  

     *  

  •  {
    @link
     #setPenRadius(double radius)}

     *  

 *  

 *  For example, {
@code
 StdDraw.setPenRadius(0.025)} makes

 *  the thickness of the lines and the size of the points to be five times

 *  the 0.005 default.

 *  To draw points with the minimum possible radius (one pixel on typical

 *  displays), set the pen radius to 0.0.

 *  

 *  Pen color.

 *  All geometric shapes (such as points, lines, and circles) are drawn using

 *  the current pen color. By default, it is black.

 *  You can change the pen color with the following methods:

 *  

     *  

  •  {
    @link
     #setPenColor(int red, int green, int blue)}

     *  

  •  {
    @link
     #setPenColor(Color color)}

     *  

 *  

 *  The first method allows you to specify colors using the RGB color system.

 *  This color picker

 *  is a convenient way to find a desired color.

 *  The second method allows you to specify colors using the

 *  {
@link
 Color} data type that is discussed in Chapter 3. Until then,

 *  you can use this method with one of these predefined colors in standard drawing:

 *  {
@link
 #BLACK}, {
@link
 #BLUE}, {
@link
 #CYAN}, {
@link
 #DARK_GRAY}, {
@link
 #GRAY},

 *  {
@link
 #GREEN}, {
@link
 #LIGHT_GRAY}, {
@link
 #MAGENTA}, {
@link
 #ORANGE},

 *  {
@link
 #PINK}, {
@link
 #RED}, {
@link
 #WHITE}, {
@link
 #YELLOW},

 *  {
@link
 #BOOK_BLUE}, {
@link
 #BOOK_LIGHT_BLUE}, {
@link
 #BOOK_RED}, and

 *  {
@link
 #PRINCETON_ORANGE}.

 *  For example, {
@code
 StdDraw.setPenColor(StdDraw.MAGENTA)} sets the

 *  pen color to magenta.

 *  

 *  Canvas size.

 *  By default, all drawing takes places in a 512-by-512 canvas.

 *  The canvas does not include the window title or window border.

 *  You can change the size of the canvas with the following method:

 *  

     *  

  •  {
    @link
     #setCanvasSize(int width, int height)}

     *  

 *  

 *  This sets the canvas size to be width-by-height pixels.

 *  It also erases the current drawing and resets the coordinate system,

 *  pen radius, pen color, and font back to their default values.

 *  Ordinarly, this method is called once, at the very beginning of a program.

 *  For example, {
@code
 StdDraw.setCanvasSize(800, 800)}

 *  sets the canvas size to be 800-by-800 pixels.

 *  

 *  Canvas scale and coordinate system.

 *  By default, all drawing takes places in the unit square, with (0, 0) at

 *  lower left and (1, 1) at upper right. You can change the default

 *  coordinate system with the following methods:

 *  

     *  

  •  {
    @link
     #setXscale(double xmin, double xmax)}

     *  

  •  {
    @link
     #setYscale(double ymin, double ymax)}

     *  

  •  {
    @link
     #setScale(double min, double max)}

     *  

 *  

 *  The arguments are the coordinates of the minimum and maximum 

 *  x– or y-coordinates that will appear in the canvas.

 *  For example, if you  wish to use the default coordinate system but

 *  leave a small margin, you can call {
@code
 StdDraw.setScale(-.05, 1.05)}.

 *  

 *  These methods change the coordinate system for subsequent drawing

 *  commands; they do not affect previous drawings.

 *  These methods do not change the canvas size; so, if the x

 *  and y-scales are different, squares will become rectangles

 *  and circles will become ellipses.

 *  

 *  Text.

 *  You can use the following methods to annotate your drawings with text:

 *  

     *  

  •  {
    @link
     #text(double x, double y, String text)}

     *  

  •  {
    @link
     #text(double x, double y, String text, double degrees)}

     *  

  •  {
    @link
     #textLeft(double x, double y, String text)}

     *  

  •  {
    @link
     #textRight(double x, double y, String text)}

     *  

 *  

 *  The first two methods write the specified text in the current font,

 *  centered at (xy).

 *  The second method allows you to rotate the text.

 *  The last two methods either left- or right-align the text at (xy).

 *  

 *  The default font is a Sans Serif font with point size 16.

 *  You can use the following method to change the font:

 *  

     *  

  •  {
    @link
     #setFont(Font font)}

     *  

 *  

 *  You use the {
@link
 Font} data type to specify the font. This allows you to

 *  choose the face, size, and style of the font. For example, the following

 *  code fragment sets the font to Arial Bold, 60 point.

 *  


 *   Font font = new Font("Arial", Font.BOLD, 60);

 *   StdDraw.setFont(font);

 *   StdDraw.text(0.5, 0.5, "Hello, World");

 *  

 *  

 *  Images.

 *  You can use the following methods to add images to your drawings:

 *  

     *  

  •  {
    @link
     #picture(double x, double y, String filename)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double degrees)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double scaledWidth, double scaledHeight)}

     *  

  •  {
    @link
     #picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees)}

     *  

 *  

 *  These methods draw the specified image, centered at (xy).

 *  The supported image formats are JPEG, PNG, and GIF.

 *  The image will display at its native size, independent of the coordinate system.

 *  Optionally, you can rotate the image a specified number of degrees counterclockwise

 *  or rescale it to fit snugly inside a width-by-height bounding box.

 *  

 *  Saving to a file.

 *  You save your image to a file using the File → Save menu option.

 *  You can also save a file programatically using the following method:

 *  

     *  

  •  {
    @link
     #save(String filename)}

     *  

 *  

 *  The supported image formats are JPEG and PNG. The filename must have either the

 *  extension   or  .

 *  We recommend using PNG for drawing that consist solely of geometric shapes and JPEG 

 *  for drawings that contains pictures.

 *  

 *  Clearing the canvas.

 *  To clear the entire drawing canvas, you can use the following methods:

 *  

     *  

  •  {
    @link
     #clear()}

     *  

  •  {
    @link
     #clear(Color color)}

     *  

 *  

 *  The first method clears the canvas to white; the second method

 *  allows you to specify a color of your choice. For example,

 *  {
@code
 StdDraw.clear(StdDraw.LIGHT_GRAY)} clears the canvas to a shade

 *  of gray.

 *  

 *  Computer animations and double buffering.

 *  Double buffering is one of the most powerful features of standard drawing,

 *  enabling computer animations.

 *  The following methods control the way in which objects are drawn:

 *  

     *  

  •  {
    @link
     #enableDoubleBuffering()}

     *  

  •  {
    @link
     #disableDoubleBuffering()}

     *  

  •  {
    @link
     #show()}

     *  

  •  {
    @link
     #pause(int t)}

     *  

 *  

 *  By default, double buffering is disabled, which means that as soon as you

 *  call a drawing

 *  method—such as {
@code
 point()} or {
@code
 line()}—the

 *  results appear on the screen.

 *  

 *  When double buffering is enabled by calling {
@link
 #enableDoubleBuffering()},

 *  all drawing takes place on the offscreen canvas. The offscreen canvas

 *  is not displayed. Only when you call

 *  {
@link
 #show()} does your drawing get copied from the offscreen canvas to

 *  the onscreen canvas, where it is displayed in the standard drawing window. You 

 *  can think of double buffering as collecting all of the lines, points, shapes,

 *  and text that you tell it to draw, and then drawing them all

 *  simultaneously, upon request.

 *  

 *  The most important use of double buffering is to produce computer

 *  animations, creating the illusion of motion by rapidly

 *  displaying static drawings. To produce an animation, repeat

 *  the following four steps:

 *  

     *  

  •  Clear the offscreen canvas.

     *  

  •  Draw objects on the offscreen canvas.

     *  

  •  Copy the offscreen canvas to the onscreen canvas.

     *  

  •  Wait for a short while.

     *  

 *  

 *  The {
@link
 #clear()}, {
@link
 #show()}, and {
@link
 #pause(int t)} methods

 *  support the first, third, and fourth of these steps, respectively.

 *  

 *  For example, this code fragment animates two balls moving in a circle.

 *  


 *   StdDraw.setScale(-2, +2);

 *   StdDraw.enableDoubleBuffering();

 *

 *   for (double t = 0.0; true; t += 0.02) {

 *       double x = Math.sin(t);

 *       double y = Math.cos(t);

 *       StdDraw.clear();

 *       StdDraw.filledCircle(x, y, 0.05);

 *       StdDraw.filledCircle(-x, -y, 0.05);

 *       StdDraw.show();

 *       StdDraw.pause(20);

 *   }

 *  

 *  

 *  Keyboard and mouse inputs.

 *  Standard drawing has very basic support for keyboard and mouse input.

 *  It is much less powerful than most user interface libraries provide, but also much simpler.

 *  You can use the following methods to intercept mouse events:

 *  

     *  

  •  {
    @link
     #isMousePressed()}

     *  

  •  {
    @link
     #mouseX()}

     *  

  •  {
    @link
     #mouseY()}

     *  

 *  

 *  The first method tells you whether a mouse button is currently being pressed.

 *  The last two methods tells you the x– and y-coordinates of the mouse’s

 *  current position, using the same coordinate system as the canvas (the unit square, by default).

 *  You should use these methods in an animation loop that waits a short while before trying

 *  to poll the mouse for its current state.

 *  You can use the following methods to intercept keyboard events:

 *  

     *  

  •  {
    @link
     #hasNextKeyTyped()}

     *  

  •  {
    @link
     #nextKeyTyped()}

     *  

  •  {
    @link
     #isKeyPressed(int keycode)}

     *  

 *  

 *  If the user types lots of keys, they will be saved in a list until you process them.

 *  The first method tells you whether the user has typed a key (that your program has

 *  not yet processed).

 *  The second method returns the next key that the user typed (that your program has

 *  not yet processed) and removes it from the list of saved keystrokes.

 *  The third method tells you whether a key is currently being pressed.

 *  

 *  Accessing control parameters.

 *  You can use the following methods to access the current pen color, pen radius,

 *  and font:

 *  

     *  

  •  {
    @link
     #getPenColor()}

     *  

  •  {
    @link
     #getPenRadius()}

     *  

  •  {
    @link
     #getFont()}

     *  

 *  

 *  These methods are useful when you want to temporarily change a

 *  control parameter and reset it back to its original value.

 *  

 *  Corner cases.

 *  Here are some corner cases.

 *  

     *  

  •  Drawing an object outside (or partly outside) the canvas is permitted.

     *       However, only the part of the object that appears inside the canvas

     *       will be visible.

     *  

  •  Any method that is passed a {
    @code
     null} argument will throw an

     *       {
    @link
     IllegalArgumentException}.

     *  

  •  Any method that is passed a {
    @link
     Double#NaN},

     *       {
    @link
     Double#POSITIVE_INFINITY}, or {
    @link
     Double#NEGATIVE_INFINITY}

     *       argument will throw an {
    @link
     IllegalArgumentException}.

     *  

  •  Due to floating-point issues, an object drawn with an x– or

     *       y-coordinate that is way outside the canvas (such as the line segment

     *       from (0.5, –10^308) to (0.5, 10^308) may not be visible even in the

     *       part of the canvas where it should be.

     *  

 *  

 *  Performance tricks.

 *  Standard drawing is capable of drawing large amounts of data.

 *  Here are a few tricks and tips:

 *  

     *  

  •  Use double buffering for static drawing with a large

     *       number of objects.

     *       That is, call {
    @link
     #enableDoubleBuffering()} before

     *       the sequence of drawing commands and call {
    @link
     #show()} afterwards.

     *       Incrementally displaying a complex drawing while it is being

     *       created can be intolerably inefficient on many computer systems.

     *  

  •  When drawing computer animations, call {
    @code
     show()}

     *       only once per frame, not after drawing each individual object.

     *  

  •  If you call {
    @code
     picture()} multiple times with the same filename,

     *       Java will cache the image, so you do not incur the cost of reading

     *       from a file each time.

     *  

 *  

 *  Known bugs and issues.

 *  

     *  

  •  The {
    @code
     picture()} methods may not draw the portion of the image that is

     *       inside the canvas if the center point (xy) is outside the

     *       canvas.

     *       This bug appears only on some systems.

     *  

 *  

 *  Reference.

 *  For additional documentation,

 *  see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdDraw
 
implements
 
ActionListener
,
 
MouseListener
,
 
MouseMotionListener
,
 
KeyListener
 
{

    
/**

     *  The color black.

     */

    
public
 
static
 
final
 
Color
 BLACK 
=
 
Color
.
BLACK
;

    
/**

     *  The color blue.

     */

    
public
 
static
 
final
 
Color
 BLUE 
=
 
Color
.
BLUE
;

    
/**

     *  The color cyan.

     */

    
public
 
static
 
final
 
Color
 CYAN 
=
 
Color
.
CYAN
;

    
/**

     *  The color dark gray.

     */

    
public
 
static
 
final
 
Color
 DARK_GRAY 
=
 
Color
.
DARK_GRAY
;

    
/**

     *  The color gray.

     */

    
public
 
static
 
final
 
Color
 GRAY 
=
 
Color
.
GRAY
;

    
/**

     *  The color green.

     */

    
public
 
static
 
final
 
Color
 GREEN  
=
 
Color
.
GREEN
;

    
/**

     *  The color light gray.

     */

    
public
 
static
 
final
 
Color
 LIGHT_GRAY 
=
 
Color
.
LIGHT_GRAY
;

    
/**

     *  The color magenta.

     */

    
public
 
static
 
final
 
Color
 MAGENTA 
=
 
Color
.
MAGENTA
;

    
/**

     *  The color orange.

     */

    
public
 
static
 
final
 
Color
 ORANGE 
=
 
Color
.
ORANGE
;

    
/**

     *  The color pink.

     */

    
public
 
static
 
final
 
Color
 PINK 
=
 
Color
.
PINK
;

    
/**

     *  The color red.

     */

    
public
 
static
 
final
 
Color
 RED 
=
 
Color
.
RED
;

    
/**

     *  The color white.

     */

    
public
 
static
 
final
 
Color
 WHITE 
=
 
Color
.
WHITE
;

    
/**

     *  The color yellow.

     */

    
public
 
static
 
final
 
Color
 YELLOW 
=
 
Color
.
YELLOW
;

    
/**

     * Shade of blue used in Introduction to Programming in Java.

     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).

     */

    
public
 
static
 
final
 
Color
 BOOK_BLUE 
=
 
new
 
Color
(
9
,
 
90
,
 
166
);

    
/**

     * Shade of light blue used in Introduction to Programming in Java.

     * The RGB values are approximately (103, 198, 243).

     */

    
public
 
static
 
final
 
Color
 BOOK_LIGHT_BLUE 
=
 
new
 
Color
(
103
,
 
198
,
 
243
);

    
/**

     * Shade of red used in Algorithms, 4th edition.

     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).

     */

    
public
 
static
 
final
 
Color
 BOOK_RED 
=
 
new
 
Color
(
150
,
 
35
,
 
31
);

    
/**

     * Shade of orange used in Princeton University’s identity.

     * It is PMS 158. The RGB values are approximately (245, 128, 37).

     */

    
public
 
static
 
final
 
Color
 PRINCETON_ORANGE 
=
 
new
 
Color
(
245
,
 
128
,
 
37
);

    
// default colors

    
private
 
static
 
final
 
Color
 DEFAULT_PEN_COLOR   
=
 BLACK
;

    
private
 
static
 
final
 
Color
 DEFAULT_CLEAR_COLOR 
=
 WHITE
;

    
// current pen color

    
private
 
static
 
Color
 penColor
;

    
// default canvas size is DEFAULT_SIZE-by-DEFAULT_SIZE

    
private
 
static
 
final
 
int
 DEFAULT_SIZE 
=
 
512
;

    
private
 
static
 
int
 width  
=
 DEFAULT_SIZE
;

    
private
 
static
 
int
 height 
=
 DEFAULT_SIZE
;

    
// default pen radius

    
private
 
static
 
final
 
double
 DEFAULT_PEN_RADIUS 
=
 
0.002
;

    
// current pen radius

    
private
 
static
 
double
 penRadius
;

    
// show we draw immediately or wait until next show?

    
private
 
static
 
boolean
 defer 
=
 
false
;

    
// boundary of drawing canvas, 0% border

    
// private static final double BORDER = 0.05;

    
private
 
static
 
final
 
double
 BORDER 
=
 
0.00
;

    
private
 
static
 
final
 
double
 DEFAULT_XMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_XMAX 
=
 
1.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMIN 
=
 
0.0
;

    
private
 
static
 
final
 
double
 DEFAULT_YMAX 
=
 
1.0
;

    
private
 
static
 
double
 xmin
,
 ymin
,
 xmax
,
 ymax
;

    
// for synchronization

    
private
 
static
 
Object
 mouseLock 
=
 
new
 
Object
();

    
private
 
static
 
Object
 keyLock 
=
 
new
 
Object
();

    
// default font

    
private
 
static
 
final
 
Font
 DEFAULT_FONT 
=
 
new
 
Font
(
“SansSerif”
,
 
Font
.
PLAIN
,
 
16
);

    
// current font

    
private
 
static
 
Font
 font
;

    
// double buffered graphics

    
private
 
static
 
BufferedImage
 offscreenImage
,
 onscreenImage
;

    
private
 
static
 
Graphics2D
 offscreen
,
 onscreen
;

    
// singleton for callbacks: avoids generation of extra .class files

    
private
 
static
 
StdDraw
 std 
=
 
new
 
StdDraw
();

    
// the frame for drawing to the screen

    
private
 
static
 
JFrame
 frame
;

    
// mouse state

    
private
 
static
 
boolean
 isMousePressed 
=
 
false
;

    
private
 
static
 
double
 mouseX 
=
 
0
;

    
private
 
static
 
double
 mouseY 
=
 
0
;

    
// queue of typed key characters

    
private
 
static
 
LinkedList
< Character >
 keysTyped 
=
 
new
 
LinkedList
< Character >
();

    
// set of key codes currently pressed down

    
private
 
static
 
TreeSet
< Integer >
 keysDown 
=
 
new
 
TreeSet
< Integer >
();

    
// singleton pattern: client can’t instantiate

    
private
 
StdDraw
()
 
{
 
}

    
// static initializer

    
static
 
{

        init
();

    
}

    
/**

     * Sets the canvas (drawing area) to be 512-by-512 pixels.

     * This also erases the current drawing and resets the coordinate system,

     * pen radius, pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning

     * of a program.

     */

    
public
 
static
 
void
 setCanvasSize
()
 
{

        setCanvasSize
(
DEFAULT_SIZE
,
 DEFAULT_SIZE
);

    
}

    
/**

     * Sets the canvas (drawing area) to be width-by-height pixels.

     * This also erases the current drawing and resets the coordinate system,

     * pen radius, pen color, and font back to their default values.

     * Ordinarly, this method is called once, at the very beginning

     * of a program.

     *

     * 
@param
  canvasWidth the width as a number of pixels

     * 
@param
  canvasHeight the height as a number of pixels

     * 
@throws
 IllegalArgumentException unless both {
@code
 canvasWidth} and

     *         {
@code
 canvasHeight} are positive

     */

    
public
 
static
 
void
 setCanvasSize
(
int
 canvasWidth
,
 
int
 canvasHeight
)
 
{

        
if
 
(
canvasWidth 
<=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );          if   ( canvasHeight  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );         width  =  canvasWidth ;         height  =  canvasHeight ;         init ();      }      // init      private   static   void  init ()   {          if   ( frame  !=   null )  frame . setVisible ( false );         frame  =   new   JFrame ();         offscreenImage  =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );         onscreenImage   =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );         offscreen  =  offscreenImage . createGraphics ();         onscreen   =  onscreenImage . createGraphics ();         offscreen . scale ( 2.0 ,   2.0 );    // since we made it 2x as big         setXscale ();         setYscale ();         offscreen . setColor ( DEFAULT_CLEAR_COLOR );         offscreen . fillRect ( 0 ,   0 ,  width ,  height );         setPenColor ();         setPenRadius ();         setFont ();         clear ();          // add antialiasing          RenderingHints  hints  =   new   RenderingHints ( RenderingHints . KEY_ANTIALIASING ,                                                    RenderingHints . VALUE_ANTIALIAS_ON );         hints . put ( RenderingHints . KEY_RENDERING ,   RenderingHints . VALUE_RENDER_QUALITY );         offscreen . addRenderingHints ( hints );          // frame stuff          RetinaImageIcon  icon  =   new   RetinaImageIcon ( onscreenImage );          JLabel  draw  =   new   JLabel ( icon );         draw . addMouseListener ( std );         draw . addMouseMotionListener ( std );         frame . setContentPane ( draw );         frame . addKeyListener ( std );      // JLabel cannot get keyboard focus         frame . setFocusTraversalKeysEnabled ( false );    // allow VK_TAB with isKeyPressed()         frame . setResizable ( false );         frame . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );              // closes all windows          // frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);      // closes only current window         frame . setTitle ( "Standard Draw" );         frame . setJMenuBar ( createMenuBar ());         frame . pack ();         frame . requestFocusInWindow ();         frame . setVisible ( true );      }      // create the menu bar (changed to private)      private   static   JMenuBar  createMenuBar ()   {          JMenuBar  menuBar  =   new   JMenuBar ();          JMenu  menu  =   new   JMenu ( "File" );         menuBar . add ( menu );          JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );         menuItem1 . addActionListener ( std );          // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()         menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,                                  Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));         menu . add ( menuItem1 );          return  menuBar ;      }     /***************************************************************************     *  User and screen coordinate systems.     ***************************************************************************/      // throw an IllegalArgumentException if x is NaN or infinite      private   static   void  validate ( double  x ,   String  name )   {          if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );          if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNonnegative ( double  x ,   String  name )   {          if   ( x  <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );      }      // throw an IllegalArgumentException if s is null      private   static   void  validateNotNull ( Object  x ,   String  name )   {          if   ( x  ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );      }      /**      * Sets the x-scale to be the default (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setXscale
()
 
{

        setXscale
(
DEFAULT_XMIN
,
 DEFAULT_XMAX
);

    
}

    
/**

     * Sets the y-scale to be the default (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setYscale
()
 
{

        setYscale
(
DEFAULT_YMIN
,
 DEFAULT_YMAX
);

    
}

    
/**

     * Sets the x-scale and y-scale to be the default

     * (between 0.0 and 1.0).

     */

    
public
 
static
 
void
 setScale
()
 
{

        setXscale
();

        setYscale
();

    
}

    
/**

     * Sets the x-scale to the specified range.

     *

     * 
@param
  min the minimum value of the x-scale

     * 
@param
  max the maximum value of the x-scale

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setXscale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            xmin 
=
 min 

 BORDER 
*
 size
;

            xmax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
/**

     * Sets the y-scale to the specified range.

     *

     * 
@param
  min the minimum value of the y-scale

     * 
@param
  max the maximum value of the y-scale

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setYscale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            ymin 
=
 min 

 BORDER 
*
 size
;

            ymax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
/**

     * Sets both the x-scale and y-scale to the (same) specified range.

     *

     * 
@param
  min the minimum value of the x– and y-scales

     * 
@param
  max the maximum value of the x– and y-scales

     * 
@throws
 IllegalArgumentException if {
@code
 (max == min)}

     * 
@throws
 IllegalArgumentException if either {
@code
 min} or {
@code
 max} is either NaN or infinite

     */

    
public
 
static
 
void
 setScale
(
double
 min
,
 
double
 max
)
 
{

        validate
(
min
,
 
“min”
);

        validate
(
max
,
 
“max”
);

        
double
 size 
=
 max 

 min
;

        
if
 
(
size 
==
 
0.0
)
 
throw
 
new
 
IllegalArgumentException
(
“the min and max are the same”
);

        
synchronized
 
(
mouseLock
)
 
{

            xmin 
=
 min 

 BORDER 
*
 size
;

            xmax 
=
 max 
+
 BORDER 
*
 size
;

            ymin 
=
 min 

 BORDER 
*
 size
;

            ymax 
=
 max 
+
 BORDER 
*
 size
;

        
}

    
}

    
// helper functions that scale from user coordinates to screen coordinates and back

    
private
 
static
 
double
  scaleX
(
double
 x
)
 
{
 
return
 width  
*
 
(


 xmin
)
 
/
 
(
xmax 

 xmin
);
 
}

    
private
 
static
 
double
  scaleY
(
double
 y
)
 
{
 
return
 height 
*
 
(
ymax 

 y
)
 
/
 
(
ymax 

 ymin
);
 
}

    
private
 
static
 
double
 factorX
(
double
 w
)
 
{
 
return
 w 
*
 width  
/
 
Math
.
abs
(
xmax 

 xmin
);
  
}

    
private
 
static
 
double
 factorY
(
double
 h
)
 
{
 
return
 h 
*
 height 
/
 
Math
.
abs
(
ymax 

 ymin
);
  
}

    
private
 
static
 
double
   userX
(
double
 x
)
 
{
 
return
 xmin 
+
 x 
*
 
(
xmax 

 xmin
)
 
/
 width
;
    
}

    
private
 
static
 
double
   userY
(
double
 y
)
 
{
 
return
 ymax 

 y 
*
 
(
ymax 

 ymin
)
 
/
 height
;
   
}

    
/**

     * Clears the screen to the default color (white).

     */

    
public
 
static
 
void
 clear
()
 
{

        clear
(
DEFAULT_CLEAR_COLOR
);

    
}

    
/**

     * Clears the screen to the specified color.

     *

     * 
@param
 color the color to make the background

     * 
@throws
 IllegalArgumentException if {
@code
 color} is {
@code
 null}

     */

    
public
 
static
 
void
 clear
(
Color
 color
)
 
{

        validateNotNull
(
color
,
 
“color”
);

        offscreen
.
setColor
(
color
);

        offscreen
.
fillRect
(
0
,
 
0
,
 width
,
 height
);

        offscreen
.
setColor
(
penColor
);

        draw
();

    
}

    
/**

     * Returns the current pen radius.

     *

     * 
@return
 the current value of the pen radius

     */

    
public
 
static
 
double
 getPenRadius
()
 
{

        
return
 penRadius
;

    
}

    
/**

     * Sets the pen size to the default size (0.002).

     * The pen is circular, so that lines have rounded ends, and when you set the

     * pen radius and draw a point, you get a circle of the specified radius.

     * The pen radius is not affected by coordinate scaling.

     */

    
public
 
static
 
void
 setPenRadius
()
 
{

        setPenRadius
(
DEFAULT_PEN_RADIUS
);

    
}

    
/**

     * Sets the radius of the pen to the specified size.

     * The pen is circular, so that lines have rounded ends, and when you set the

     * pen radius and draw a point, you get a circle of the specified radius.

     * The pen radius is not affected by coordinate scaling.

     *

     * 
@param
  radius the radius of the pen

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative, NaN, or infinite

     */

    
public
 
static
 
void
 setPenRadius
(
double
 radius
)
 
{

        validate
(
radius
,
 
“pen radius”
);

        validateNonnegative
(
radius
,
 
“pen radius”
);

        penRadius 
=
 radius
;

        
float
 scaledPenRadius 
=
 
(
float
)
 
(
radius 
*
 DEFAULT_SIZE
);

        
BasicStroke
 stroke 
=
 
new
 
BasicStroke
(
scaledPenRadius
,
 
BasicStroke
.
CAP_ROUND
,
 
BasicStroke
.
JOIN_ROUND
);

        
// BasicStroke stroke = new BasicStroke(scaledPenRadius);

        offscreen
.
setStroke
(
stroke
);

    
}

    
/**

     * Returns the current pen color.

     *

     * 
@return
 the current pen color

     */

    
public
 
static
 
Color
 getPenColor
()
 
{

        
return
 penColor
;

    
}

    
/**

     * Sets the pen color to the default color (black).

     */

    
public
 
static
 
void
 setPenColor
()
 
{

        setPenColor
(
DEFAULT_PEN_COLOR
);

    
}

    
/**

     * Sets the pen color to the specified color.

     * 

     * The predefined pen colors are

     * {
@code
 StdDraw.BLACK}, {
@code
 StdDraw.BLUE}, {
@code
 StdDraw.CYAN},

     * {
@code
 StdDraw.DARK_GRAY}, {
@code
 StdDraw.GRAY}, {
@code
 StdDraw.GREEN},

     * {
@code
 StdDraw.LIGHT_GRAY}, {
@code
 StdDraw.MAGENTA}, {
@code
 StdDraw.ORANGE},

     * {
@code
 StdDraw.PINK}, {
@code
 StdDraw.RED}, {
@code
 StdDraw.WHITE}, and

     * {
@code
 StdDraw.YELLOW}.

     *

     * 
@param
 color the color to make the pen

     * 
@throws
 IllegalArgumentException if {
@code
 color} is {
@code
 null}

     */

    
public
 
static
 
void
 setPenColor
(
Color
 color
)
 
{

        validateNotNull
(
color
,
 
“color”
);

        penColor 
=
 color
;

        offscreen
.
setColor
(
penColor
);

    
}

    
/**

     * Sets the pen color to the specified RGB color.

     *

     * 
@param
  red the amount of red (between 0 and 255)

     * 
@param
  green the amount of green (between 0 and 255)

     * 
@param
  blue the amount of blue (between 0 and 255)

     * 
@throws
 IllegalArgumentException if {
@code
 red}, {
@code
 green},

     *         or {
@code
 blue} is outside its prescribed range

     */

    
public
 
static
 
void
 setPenColor
(
int
 red
,
 
int
 green
,
 
int
 blue
)
 
{

        
if
 
(
red   
<   0   ||  red    >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“red must be between 0 and 255”
);

        
if
 
(
green 
<   0   ||  green  >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“green must be between 0 and 255”
);

        
if
 
(
blue  
<   0   ||  blue   >=
 
256
)
 
throw
 
new
 
IllegalArgumentException
(
“blue must be between 0 and 255”
);

        setPenColor
(
new
 
Color
(
red
,
 green
,
 blue
));

    
}

    
/**

     * Returns the current font.

     *

     * 
@return
 the current font

     */

    
public
 
static
 
Font
 getFont
()
 
{

        
return
 font
;

    
}

    
/**

     * Sets the font to the default font (sans serif, 16 point).

     */

    
public
 
static
 
void
 setFont
()
 
{

        setFont
(
DEFAULT_FONT
);

    
}

    
/**

     * Sets the font to the specified value.

     *

     * 
@param
 font the font

     * 
@throws
 IllegalArgumentException if {
@code
 font} is {
@code
 null}

     */

    
public
 
static
 
void
 setFont
(
Font
 font
)
 
{

        validateNotNull
(
font
,
 
“font”
);

        
StdDraw
.
font 
=
 font
;

    
}

   
/***************************************************************************

    *  Drawing geometric shapes.

    ***************************************************************************/

    
/**

     * Draws a line segment between (x0y0) and

     * (x1y1).

     *

     * 
@param
  x0 the x-coordinate of one endpoint

     * 
@param
  y0 the y-coordinate of one endpoint

     * 
@param
  x1 the x-coordinate of the other endpoint

     * 
@param
  y1 the y-coordinate of the other endpoint

     * 
@throws
 IllegalArgumentException if any coordinate is either NaN or infinite

     */

    
public
 
static
 
void
 line
(
double
 x0
,
 
double
 y0
,
 
double
 x1
,
 
double
 y1
)
 
{

        validate
(
x0
,
 
“x0”
);

        validate
(
y0
,
 
“y0”
);

        validate
(
x1
,
 
“x1”
);

        validate
(
y1
,
 
“y1”
);

        offscreen
.
draw
(
new
 
Line2D
.
Double
(
scaleX
(
x0
),
 scaleY
(
y0
),
 scaleX
(
x1
),
 scaleY
(
y1
)));

        draw
();

    
}

    
/**

     * Draws one pixel at (xy).

     * This method is private because pixels depend on the display.

     * To achieve the same effect, set the pen radius to 0 and call {
@code
 point()}.

     *

     * 
@param
  x the x-coordinate of the pixel

     * 
@param
  y the y-coordinate of the pixel

     * 
@throws
 IllegalArgumentException if {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
private
 
static
 
void
 pixel
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        offscreen
.
fillRect
((
int
)
 
Math
.
round
(
scaleX
(
x
)),
 
(
int
)
 
Math
.
round
(
scaleY
(
y
)),
 
1
,
 
1
);

    
}

    
/**

     * Draws a point centered at (xy).

     * The point is a filled circle whose radius is equal to the pen radius.

     * To draw a single-pixel point, first set the pen radius to 0.

     *

     * 
@param
 x the x-coordinate of the point

     * 
@param
 y the y-coordinate of the point

     * 
@throws
 IllegalArgumentException if either {
@code
 x} or {
@code
 y} is either NaN or infinite

     */

    
public
 
static
 
void
 point
(
double
 x
,
 
double
 y
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 r 
=
 penRadius
;

        
float
 scaledPenRadius 
=
 
(
float
)
 
(

*
 DEFAULT_SIZE
);

        
// double ws = factorX(2*r);

        
// double hs = factorY(2*r);

        
// if (ws <= 1 && hs <= 1) pixel(x, y);          if   ( scaledPenRadius  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  scaledPenRadius / 2 ,  ys  -  scaledPenRadius / 2 ,                                                  scaledPenRadius ,  scaledPenRadius ));         draw ();      }      /**      * Draws a circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
static
 
void
 circle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“radius”
);

        validateNonnegative
(
radius
,
 
“radius”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
radius
);

        
double
 hs 
=
 factorY
(
2
*
radius
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a filled circle of the specified radius, centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
static
 
void
 filledCircle
(
double
 x
,
 
double
 y
,
 
double
 radius
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“radius”
);

        validateNonnegative
(
radius
,
 
“radius”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
radius
);

        
double
 hs 
=
 factorY
(
2
*
radius
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws an ellipse with the specified semimajor and semiminor axes,      * centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the ellipse

     * 
@param
  y the y-coordinate of the center of the ellipse

     * 
@param
  semiMajorAxis is the semimajor axis of the ellipse

     * 
@param
  semiMinorAxis is the semiminor axis of the ellipse

     * 
@throws
 IllegalArgumentException if either {
@code
 semiMajorAxis}

     *         or {
@code
 semiMinorAxis} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
static
 
void
 ellipse
(
double
 x
,
 
double
 y
,
 
double
 semiMajorAxis
,
 
double
 semiMinorAxis
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
semiMajorAxis
,
 
“semimajor axis”
);

        validate
(
semiMinorAxis
,
 
“semiminor axis”
);

        validateNonnegative
(
semiMajorAxis
,
 
“semimajor axis”
);

        validateNonnegative
(
semiMinorAxis
,
 
“semiminor axis”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
semiMajorAxis
);

        
double
 hs 
=
 factorY
(
2
*
semiMinorAxis
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a filled ellipse with the specified semimajor and semiminor axes,      * centered at (xy).

     *

     * 
@param
  x the x-coordinate of the center of the ellipse

     * 
@param
  y the y-coordinate of the center of the ellipse

     * 
@param
  semiMajorAxis is the semimajor axis of the ellipse

     * 
@param
  semiMinorAxis is the semiminor axis of the ellipse

     * 
@throws
 IllegalArgumentException if either {
@code
 semiMajorAxis}

     *         or {
@code
 semiMinorAxis} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
static
 
void
 filledEllipse
(
double
 x
,
 
double
 y
,
 
double
 semiMajorAxis
,
 
double
 semiMinorAxis
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
semiMajorAxis
,
 
“semimajor axis”
);

        validate
(
semiMinorAxis
,
 
“semiminor axis”
);

        validateNonnegative
(
semiMajorAxis
,
 
“semimajor axis”
);

        validateNonnegative
(
semiMinorAxis
,
 
“semiminor axis”
);

        
double
 xs 
=
 scaleX
(
x
);

        
double
 ys 
=
 scaleY
(
y
);

        
double
 ws 
=
 factorX
(
2
*
semiMajorAxis
);

        
double
 hs 
=
 factorY
(
2
*
semiMinorAxis
);

        
if
 
(
ws 
<=   1   &&  hs  <=   1 )  pixel ( x ,  y );          else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));         draw ();      }      /**      * Draws a circular arc of the specified radius,      * centered at (xy), from angle1 to angle2 (in degrees).

     *

     * 
@param
  x the x-coordinate of the center of the circle

     * 
@param
  y the y-coordinate of the center of the circle

     * 
@param
  radius the radius of the circle

     * 
@param
  angle1 the starting angle. 0 would mean an arc beginning at 3 o’clock.

     * 
@param
  angle2 the angle at the end of the arc. For example, if

     *         you want a 90 degree arc, then angle2 should be angle1 + 90.

     * 
@throws
 IllegalArgumentException if {
@code
 radius} is negative

     * 
@throws
 IllegalArgumentException if any argument is either NaN or infinite

     */

    
public
 
static
 
void
 arc
(
double
 x
,
 
double
 y
,
 
double
 radius
,
 
double
 angle1
,
 
double
 angle2
)
 
{

        validate
(
x
,
 
“x”
);

        validate
(
y
,
 
“y”
);

        validate
(
radius
,
 
“arc radius”
);

        validate
(
angle1
,
 
“angle1”
);

        validate
(
angle2
,
 
“angle2”
);

        validateNonnegative
(
radius
,
 
“arc radius”
);

        while (angle2 < angle1) angle2 += 360;         double xs = scaleX(x);         double ys = scaleY(y);         double ws = factorX(2*radius);         double hs = factorY(2*radius);         if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Arc2D.Double(xs - ws/2, ys - hs/2, ws, hs, angle1, angle2 - angle1, Arc2D.OPEN));         draw();     }     /**     * Draws a square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void square(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled square of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the square     * @param  y the y-coordinate of the center of the square     * @param  halfLength one half the length of any side of the square     * @throws IllegalArgumentException if {@code halfLength} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledSquare(double x, double y, double halfLength) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfLength, “halfLength”);

        validateNonnegative(halfLength, “half length”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfLength);

        double hs = factorY(2*halfLength);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void rectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.draw(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a filled rectangle of the specified size, centered at (xy).     *     * @param  x the x-coordinate of the center of the rectangle     * @param  y the y-coordinate of the center of the rectangle     * @param  halfWidth one half the width of the rectangle     * @param  halfHeight one half the height of the rectangle     * @throws IllegalArgumentException if either {@code halfWidth} or {@code halfHeight} is negative     * @throws IllegalArgumentException if any argument is either NaN or infinite     */

    public static void filledRectangle(double x, double y, double halfWidth, double halfHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(halfWidth, “halfWidth”);

        validate(halfHeight, “halfHeight”);

        validateNonnegative(halfWidth, “half width”);

        validateNonnegative(halfHeight, “half height”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(2*halfWidth);

        double hs = factorY(2*halfHeight);

        if (ws <= 1 && hs <= 1) pixel(x, y);         else offscreen.fill(new Rectangle2D.Double(xs - ws/2, ys - hs/2, ws, hs));         draw();     }     /**     * Draws a polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public static void polygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.draw(path);         draw();     }     /**     * Draws a filled polygon with the vertices      * (x0y0),     * (x1y1), …,     * (xn–1yn–1).     *     * @param  x an array of all the x-coordinates of the polygon     * @param  y an array of all the y-coordinates of the polygon     * @throws IllegalArgumentException unless {@code x[]} and {@code y[]}     *         are of the same length     * @throws IllegalArgumentException if any coordinate is either NaN or infinite     * @throws IllegalArgumentException if either {@code x[]} or {@code y[]} is {@code null}     */

    public static void filledPolygon(double[] x, double[] y) {

        validateNotNull(x, “x-coordinate array”);

        validateNotNull(y, “y-coordinate array”);

        for (int i = 0; i < x.length; i++) validate(x[i], "x[" + i + "]");         for (int i = 0; i < y.length; i++) validate(y[i], "y[" + i + "]");         int n1 = x.length;         int n2 = y.length;         if (n1 != n2) throw new IllegalArgumentException("arrays must be of the same length");         int n = n1;         if (n == 0) return;         GeneralPath path = new GeneralPath();         path.moveTo((float) scaleX(x[0]), (float) scaleY(y[0]));         for (int i = 0; i < n; i++)             path.lineTo((float) scaleX(x[i]), (float) scaleY(y[i]));         path.closePath();         offscreen.fill(path);         draw();     }    /***************************************************************************    *  Drawing images.    ***************************************************************************/     // get an image from the given filename    private static Image getImage(String filename) {         if (filename == null) throw new IllegalArgumentException();         // to read from file        ImageIcon icon = new ImageIcon(filename);         // try to read from URL        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             try {                 URL url = new URL(filename);                 icon = new ImageIcon(url);             }             catch (MalformedURLException e) {                 /* not a url */             }         }         // in case file is inside a .jar (classpath relative to StdDraw)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource(filename);             if (url != null)                 icon = new ImageIcon(url);         }         // in case file is inside a .jar (classpath relative to root of jar)        if ((icon == null) || (icon.getImageLoadStatus() != MediaTracker.COMPLETE)) {             URL url = StdDraw.class.getResource("/" + filename);             if (url == null) throw new IllegalArgumentException("image " + filename + " not found");             icon = new ImageIcon(url);         }         return icon.getImage();     }    /***************************************************************************    * [Summer 2016] Should we update to use ImageIO instead of ImageIcon()?    *               Seems to have some issues loading images on some systems    *               and slows things down on other systems.    *               especially if you don't call ImageIO.setUseCache(false)    *               One advantage is that it returns a BufferedImage.    ***************************************************************************/ /*    private static BufferedImage getImage(String filename) {        if (filename == null) throw new IllegalArgumentException();         // from a file or URL        try {            URL url = new URL(filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }         // in case file is inside a .jar (classpath relative to StdDraw)        try {            URL url = StdDraw.class.getResource(filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }         // in case file is inside a .jar (classpath relative to root of jar)        try {            URL url = StdDraw.class.getResource("/" + filename);            BufferedImage image = ImageIO.read(url);            return image;        }         catch (IOException e) {            // ignore        }        throw new IllegalArgumentException("image " + filename + " not found");    }*/     /**     * Draws the specified image centered at (xy).     * The supported image formats are JPEG, PNG, and GIF.     * As an optimization, the picture is cached, so there is no performance     * penalty for redrawing the same image multiple times (e.g., in an animation).     * However, if you change the picture file after drawing it, subsequent     * calls will draw the original picture.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if either {@code x} or {@code y} is either NaN or infinite     */

    public static void picture(double x, double y, String filename) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(filename, “filename”);

        // BufferedImage image = getImage(filename);        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = image.getWidth();    // can call only if image is a BufferedImage        // int hs = image.getHeight();        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         draw();     }     /**     * Draws the specified image centered at (xy),     * rotated given number of degrees.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x}, {@code y}, {@code degrees} is NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void picture(double x, double y, String filename, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        // BufferedImage image = getImage(filename);        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        // int ws = image.getWidth();    // can call only if image is a BufferedImage        // int hs = image.getHeight();        int ws = image.getWidth(null);

        int hs = image.getHeight(null);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0), (int) Math.round(ys - hs/2.0), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }     /**     * Draws the specified image centered at (xy),     * rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void picture(double x, double y, String filename, double scaledWidth, double scaledHeight) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         else {             offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                        (int) Math.round(ys - hs/2.0),                                        (int) Math.round(ws),                                        (int) Math.round(hs), null);         }         draw();     }     /**     * Draws the specified image centered at (xy), rotated     * given number of degrees, and rescaled to the specified bounding box.     * The supported image formats are JPEG, PNG, and GIF.     *     * @param  x the center x-coordinate of the image     * @param  y the center y-coordinate of the image     * @param  filename the name of the image/picture, e.g., “ball.gif”     * @param  scaledWidth the width of the scaled image (in screen coordinates)     * @param  scaledHeight the height of the scaled image (in screen coordinates)     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if either {@code scaledWidth}     *         or {@code scaledHeight} is negative     * @throws IllegalArgumentException if the image filename is invalid     */

    public static void picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(scaledWidth, “scaled width”);

        validate(scaledHeight, “scaled height”);

        validate(degrees, “degrees”);

        validateNotNull(filename, “filename”);

        validateNonnegative(scaledWidth, “scaled width”);

        validateNonnegative(scaledHeight, “scaled height”);

        Image image = getImage(filename);

        double xs = scaleX(x);

        double ys = scaleY(y);

        double ws = factorX(scaledWidth);

        double hs = factorY(scaledHeight);

        if (ws < 0 || hs < 0) throw new IllegalArgumentException("image " + filename + " is corrupt");         if (ws <= 1 && hs <= 1) pixel(x, y);         offscreen.rotate(Math.toRadians(-degrees), xs, ys);         offscreen.drawImage(image, (int) Math.round(xs - ws/2.0),                                    (int) Math.round(ys - hs/2.0),                                    (int) Math.round(ws),                                    (int) Math.round(hs), null);         offscreen.rotate(Math.toRadians(+degrees), xs, ys);         draw();     }    /***************************************************************************    *  Drawing text.    ***************************************************************************/     /**     * Writes the given text string in the current font, centered at (xy).     *     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void text(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws/2.0), (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, centered at (xy) and     * rotated by the specified number of degrees.     * @param  x the center x-coordinate of the text     * @param  y the center y-coordinate of the text     * @param  text the text to write     * @param  degrees is the number of degrees to rotate counterclockwise     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x}, {@code y}, or {@code degrees} is either NaN or infinite     */

    public static void text(double x, double y, String text, double degrees) {

        validate(x, “x”);

        validate(y, “y”);

        validate(degrees, “degrees”);

        validateNotNull(text, “text”);

        double xs = scaleX(x);

        double ys = scaleY(y);

        offscreen.rotate(Math.toRadians(-degrees), xs, ys);

        text(x, y, text);

        offscreen.rotate(Math.toRadians(+degrees), xs, ys);

    }

    /**     * Writes the given text string in the current font, left-aligned at (xy).     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void textLeft(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) xs, (float) (ys + hs));

        draw();

    }

    /**     * Writes the given text string in the current font, right-aligned at (xy).     *     * @param  x the x-coordinate of the text     * @param  y the y-coordinate of the text     * @param  text the text to write     * @throws IllegalArgumentException if {@code text} is {@code null}     * @throws IllegalArgumentException if {@code x} or {@code y} is either NaN or infinite     */

    public static void textRight(double x, double y, String text) {

        validate(x, “x”);

        validate(y, “y”);

        validateNotNull(text, “text”);

        offscreen.setFont(font);

        FontMetrics metrics = offscreen.getFontMetrics();

        double xs = scaleX(x);

        double ys = scaleY(y);

        int ws = metrics.stringWidth(text);

        int hs = metrics.getDescent();

        offscreen.drawString(text, (float) (xs – ws), (float) (ys + hs));

        draw();

    }

    /**     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds     * and enables double buffering.     * @param t number of milliseconds     * @deprecated replaced by {@link #enableDoubleBuffering()}, {@link #show()}, and {@link #pause(int t)}     */

    @Deprecated

    public static void show(int t) {

        validateNonnegative(t, “t”);

        show();

        pause(t);

        enableDoubleBuffering();

    }

    /**     * Pauses for t milliseconds. This method is intended to support computer animations.     * @param t number of milliseconds     */

    public static void pause(int t) {

        validateNonnegative(t, “t”);

        try {

            Thread.sleep(t);

        }

        catch (InterruptedException e) {

            System.out.println(“Error sleeping”);

        }

    }

    /**     * Copies offscreen buffer to onscreen buffer. There is no reason to call     * this method unless double buffering is enabled.     */

    public static void show() {

        onscreen.drawImage(offscreenImage, 0, 0, null);

        frame.repaint();

    }

    // draw onscreen if defer is false    private static void draw() {

        if (!defer) show();

    }

    /**     * Enables double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be deferred until the next call     * to show(). Useful for animations.     */

    public static void enableDoubleBuffering() {

        defer = true;

    }

    /**     * Disables double buffering. All subsequent calls to      * drawing methods such as {@code line()}, {@code circle()},     * and {@code square()} will be displayed on screen when called.     * This is the default.     */

    public static void disableDoubleBuffering() {

        defer = false;

    }

   /***************************************************************************    *  Save drawing to a file.    ***************************************************************************/

    /**     * Saves the drawing to using the specified filename.     * The supported image formats are JPEG and PNG;     * the filename suffix must be {@code  } or {@code  }.     *     * @param  filename the name of the file with one of the required suffixes     * @throws IllegalArgumentException if {@code filename} is {@code null}     */

    public static void save(String filename) {

        validateNotNull(filename, “filename”);

        File file = new File(filename);

        String suffix = filename.substring(filename.lastIndexOf(‘.’) + 1);

        // png files        if (“png”.equalsIgnoreCase(suffix)) {

            try {

                ImageIO.write(onscreenImage, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        // need to change from ARGB to RGB for JPEG        // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727        else if (“jpg”.equalsIgnoreCase(suffix)) {

            WritableRaster raster = onscreenImage.getRaster();

            WritableRaster newRaster;

            newRaster = raster.createWritableChild(0, 0, width, height, 0, 0, new int[] {0, 1, 2});

            DirectColorModel cm = (DirectColorModel) onscreenImage.getColorModel();

            DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(),

                                                          cm.getRedMask(),

                                                          cm.getGreenMask(),

                                                          cm.getBlueMask());

            BufferedImage rgbBuffer = new BufferedImage(newCM, newRaster, false,  null);

            try {

                ImageIO.write(rgbBuffer, suffix, file);

            }

            catch (IOException e) {

                e.printStackTrace();

            }

        }

        else {

            System.out.println(“Invalid image file type: ” + suffix);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void actionPerformed(ActionEvent e) {

        FileDialog chooser = new FileDialog(StdDraw.frame, “Use a   or   extension”, FileDialog.SAVE);

        chooser.setVisible(true);

        String filename = chooser.getFile();

        if (filename != null) {

            StdDraw.save(chooser.getDirectory() + File.separator + chooser.getFile());

        }

    }

   /***************************************************************************    *  Mouse interactions.    ***************************************************************************/

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed; {@code false} otherwise     */

    public static boolean isMousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns true if the mouse is being pressed.     *     * @return {@code true} if the mouse is being pressed; {@code false} otherwise     * @deprecated replaced by {@link #isMousePressed()}     */

    @Deprecated

    public static boolean mousePressed() {

        synchronized (mouseLock) {

            return isMousePressed;

        }

    }

    /**     * Returns the x-coordinate of the mouse.     *     * @return the x-coordinate of the mouse     */

    public static double mouseX() {

        synchronized (mouseLock) {

            return mouseX;

        }

    }

    /**     * Returns the y-coordinate of the mouse.     *     * @return y-coordinate of the mouse     */

    public static double mouseY() {

        synchronized (mouseLock) {

            return mouseY;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseClicked(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseEntered(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseExited(MouseEvent e) {

        // this body is intentionally left empty    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mousePressed(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

            isMousePressed = true;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseReleased(MouseEvent e) {

        synchronized (mouseLock) {

            isMousePressed = false;

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseDragged(MouseEvent e)  {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void mouseMoved(MouseEvent e) {

        synchronized (mouseLock) {

            mouseX = StdDraw.userX(e.getX());

            mouseY = StdDraw.userY(e.getY());

        }

    }

   /***************************************************************************    *  Keyboard interactions.    ***************************************************************************/

    /**     * Returns true if the user has typed a key (that has not yet been processed).     *     * @return {@code true} if the user has typed a key (that has not yet been processed     *         by {@link #nextKeyTyped()}; {@code false} otherwise     */

    public static boolean hasNextKeyTyped() {

        synchronized (keyLock) {

            return !keysTyped.isEmpty();

        }

    }

    /**     * Returns the next key that was typed by the user (that your program has not already processed).     * This method should be preceded by a call to {@link #hasNextKeyTyped()} to ensure     * that there is a next key to process.     * This method returns a Unicode character corresponding to the key     * typed (such as {@code ‘a’} or {@code ‘A’}).     * It cannot identify action keys (such as F1 and arrow keys)     * or modifier keys (such as control).     *     * @return the next key typed by the user (that your program has not already processed).     * @throws NoSuchElementException if there is no remaining key     */

    public static char nextKeyTyped() {

        synchronized (keyLock) {

            if (keysTyped.isEmpty()) {

                throw new NoSuchElementException(“your program has already processed all keystrokes”);

            }

            return keysTyped.remove(keysTyped.size() – 1);

            // return keysTyped.removeLast();        }

    }

    /**     * Returns true if the given key is being pressed.     * 

     * This method takes the keycode (corresponding to a physical key)    *  as an argument. It can handle action keys     * (such as F1 and arrow keys) and modifier keys (such as shift and control).     * See {@link KeyEvent} for a description of key codes.     *     * @param  keycode the key to check if it is being pressed     * @return {@code true} if {@code keycode} is currently being pressed;     *         {@code false} otherwise     */

    public static boolean isKeyPressed(int keycode) {

        synchronized (keyLock) {

            return keysDown.contains(keycode);

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyTyped(KeyEvent e) {

        synchronized (keyLock) {

            keysTyped.addFirst(e.getKeyChar());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyPressed(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.add(e.getKeyCode());

        }

    }

    /**     * This method cannot be called directly.     */

    @Override

    public void keyReleased(KeyEvent e) {

        synchronized (keyLock) {

            keysDown.remove(e.getKeyCode());

        }

    }

   /***************************************************************************    *  For improved resolution on Mac Retina displays.    ***************************************************************************/

    private static class RetinaImageIcon extends ImageIcon {

            public RetinaImageIcon(Image image) {

            super(image);

        }

        public int getIconWidth() {

            return super.getIconWidth() / 2;

        }

        /**         * Gets the height of the icon.         *         * @return the height in pixels of this icon         */

        public int getIconHeight() {

            return super.getIconHeight() / 2;

        }

        public synchronized void paintIcon(Component c, Graphics g, int x, int y) {

            Graphics2D g2 = (Graphics2D) g.create();

            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);

            g2.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

            g2.scale(0.5, 0.5);

            super.paintIcon(c, g2, x * 2, y * 2);

            g2.dispose();

        }

    }

    /**     * Test client.     *     * @param args the command-line arguments     */

    public static void main(String[] args) {

        StdDraw.square(0.2, 0.8, 0.1);

        StdDraw.filledSquare(0.8, 0.8, 0.2);

        StdDraw.circle(0.8, 0.2, 0.2);

        StdDraw.setPenColor(StdDraw.BOOK_RED);

        StdDraw.setPenRadius(0.02);

        StdDraw.arc(0.8, 0.2, 0.1, 200, 45);

        // draw a blue diamond        StdDraw.setPenRadius();

        StdDraw.setPenColor(StdDraw.BOOK_BLUE);

        double[] x = { 0.1, 0.2, 0.3, 0.2 };

        double[] y = { 0.2, 0.3, 0.2, 0.1 };

        StdDraw.filledPolygon(x, y);

        // text        StdDraw.setPenColor(StdDraw.BLACK);

        StdDraw.text(0.2, 0.5, “black text”);

        StdDraw.setPenColor(StdDraw.WHITE);

        StdDraw.text(0.8, 0.8, “white text”);

    }

}

StdIn.java
StdIn.java
/******************************************************************************

 *  Compilation:  javac StdIn.java

 *  Execution:    java StdIn   (interactive test of basic functionality)

 *  Dependencies: none

 *

 *  Reads in data of various types from standard input.

 *

 ******************************************************************************/

import
 java
.
util
.
ArrayList
;

import
 java
.
util
.
InputMismatchException
;

import
 java
.
util
.
Locale
;

import
 java
.
util
.
NoSuchElementException
;

import
 java
.
util
.
Scanner
;

import
 java
.
util
.
regex
.
Pattern
;

/**

 *  The {
@code
 StdIn} class provides static methods for reading strings

 *  and numbers from standard input.

 *  These functions fall into one of four categories:

 *  

     *  

  • those for reading individual tokens from standard input, one at a time,

     *      and converting each to a number, string, or boolean

     *  

  • those for reading characters from standard input, one at a time

     *  

  • those for reading lines from standard input, one at a time

     *  

  • those for reading a sequence of values of the same type from standard input,

     *      and returning the values in an array

     *  

 *  

 *  Generally, it is best not to mix functions from the different

 *  categories in the same program.

 *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdIn.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdIn.java

 *  and put a copy in your working directory.

 *  

 *  Reading tokens from standard input and converting to numbers and strings.

 *  You can use the following methods to read numbers, strings, and booleans

 *  from standard input one at a time:

 *  

     *  

  •  {
    @link
     #isEmpty()}

     *  

  •  {
    @link
     #readInt()}

     *  

  •  {
    @link
     #readDouble()}

     *  

  •  {
    @link
     #readString()}

     *  

  •  {
    @link
     #readShort()}

     *  

  •  {
    @link
     #readLong()}

     *  

  •  {
    @link
     #readFloat()}

     *  

  •  {
    @link
     #readByte()}

     *  

  •  {
    @link
     #readBoolean()}

     *  

 *  

 *  The first method returns true if standard input has no more tokens.

 *  Each other method skips over any input that is whitespace. Then, it reads

 *  the next token and attempts to convert it into a value of the specified

 *  type. If it succeeds, it returns that value; otherwise, it

 *  throws an {
@link
 InputMismatchException}.

 *  

 *  Whitespace includes spaces, tabs, and newlines; the full definition

 *  is inherited from {
@link
 Character#isWhitespace(char)}.

 *  A token is a maximal sequence of non-whitespace characters.

 *  The precise rules for describing which tokens can be converted to

 *  integers and floating-point numbers are inherited from

 *  Scanner,

 *  using the locale {
@link
 Locale#US}; the rules

 *  for floating-point numbers are slightly different

 *  from those in {
@link
 Double#valueOf(String)},

 *  but unlikely to be of concern to most programmers.

 *  

 *  As an example, the following code fragment reads integers from standard input,

 *  one at a time, and prints them one per line.

 *  


 *  while (!StdIn.isEmpty()) {

 *      double value = StdIn.readDouble();

 *      StdOut.println(value);

 *  }

 *  

 *  

 *  Reading characters from standard input.

 *  You can use the following two methods to read characters from standard input one at a time:

 *  

     *  

  •  {
    @link
     #hasNextChar()}

     *  

  •  {
    @link
     #readChar()}

     *  

 *  

 *  The first method returns true if standard input has more input (including whitespace).

 *  The second method reads and returns the next character of input on standard 

 *  input (possibly a whitespace character).

 *  

 *  As an example, the following code fragment reads characters from standard input,

 *  one character at a time, and prints it to standard output.

 *  


 *  while (StdIn.hasNextChar()) {

 *      char c = StdIn.readChar();

 *      StdOut.print(c);

 *  }

 *  

 *  

 *  Reading lines from standard input.

 *  You can use the following two methods to read lines from standard input:

 *  

     *  

  •  {
    @link
     #hasNextLine()}

     *  

  •  {
    @link
     #readLine()}

     *  

 *  

 *  The first method returns true if standard input has more input (including whitespace).

 *  The second method reads and returns the remaining portion of 

 *  the next line of input on standard input (possibly whitespace),

 *  discarding the trailing line separator.

 *  

 *  A line separator is defined to be one of the following strings:

 *  {
@code
 \n} (Linux), {
@code
 \r} (old Macintosh),

 *  {
@code
 \r\n} (Windows),

 *  {
@code
 \}{
@code
 u2028}, {
@code
 \}{
@code
 u2029}, or {
@code
 \}{
@code
 u0085}.

 *  

 *  As an example, the following code fragment reads text from standard input,

 *  one line at a time, and prints it to standard output.

 *  


 *  while (StdIn.hasNextLine()) {

 *      String line = StdIn.readLine();

 *      StdOut.println(line);

 *  }

 *  

 *  

 *  Reading a sequence of values of the same type from standard input.

 *  You can use the following methods to read a sequence numbers, strings,

 *  or booleans (all of the same type) from standard input:

 *  

     *  

  •  {
    @link
     #readAllDoubles()}

     *  

  •  {
    @link
     #readAllInts()}

     *  

  •  {
    @link
     #readAllLongs()}

     *  

  •  {
    @link
     #readAllStrings()}

     *  

  •  {
    @link
     #readAllLines()}

     *  

  •  {
    @link
     #readAll()}

     *  

 *  

 *  The first three methods read of all of remaining token on standard input

 *  and converts the tokens to values of

 *  the specified type, as in the corresponding

 *  {
@code
 readDouble}, {
@code
 readInt}, and {
@code
 readString()} methods.

 *  The {
@code
 readAllLines()} method reads all remaining lines on standard

 *  input and returns them as an array of strings.

 *  The {
@code
 readAll()} method reads all remaining input on standard

 *  input and returns it as a string.

 *  

 *  As an example, the following code fragment reads all of the remaining

 *  tokens from standard input and returns them as an array of strings.

 *  


 *  String[] words = StdIn.readAllStrings();

 *  

 *  

 *  Differences with Scanner.

 *  {
@code
 StdIn} and {
@link
 Scanner} are both designed to parse 

 *  tokens and convert them to primitive types and strings.

 *  The main differences are summarized below:

 *  

     *  

  •  {
    @code
     StdIn} is a set of static methods and reads 

     *       reads input from only standard input. It is suitable for use before

     *       a programmer knows about objects.

     *       See {
    @link
     In} for an object-oriented version that handles

     *       input from files, URLs,

     *       and sockets.

     *  

  •  {
    @code
     StdIn} uses whitespace as the delimiter pattern

     *       that separates tokens.

     *       {
    @link
     Scanner} supports arbitrary delimiter patterns.

     *  

  •  {
    @code
     StdIn} coerces the character-set encoding to UTF-8,

     *       which is the most widely used character encoding for Unicode.

     *  

  •  {
    @code
     StdIn} coerces the locale to {
    @link
     Locale#US},

     *       for consistency with {
    @link
     StdOut}, {
    @link
     Double#parseDouble(String)},

     *       and floating-point literals.

     *  

  •  {
    @code
     StdIn} has convenient methods for reading a single

     *       character; reading in sequences of integers, doubles, or strings;

     *       and reading in all of the remaining input.

     *  

 *  

 *  Historical note: {
@code
 StdIn} preceded {
@code
 Scanner}; when

 *  {
@code
 Scanner} was introduced, this class was re-implemented to use {
@code
 Scanner}.

 *  

 *  Using standard input.

 *  Standard input is a fundamental operating system abstraction on Mac OS X,

 *  Windows, and Linux.

 *  The methods in {
@code
 StdIn} are blocking, which means that they

 *  will wait until you enter input on standard input.

 *  If your program has a loop that repeats until standard input is empty,

 *  you must signal that the input is finished.

 *  To do so, depending on your operating system and IDE, 

 *  use either {
@code
 } or {
@code
 }, on its own line.

 *  If you are redirecting standard input from a file, you will not need

 *  to do anything to signal that the input is finished.

 *  

 *  Known bugs.

 *  Java’s UTF-8 encoding does not recognize the optional 

 *  byte-order mask.

 *  If the input begins with the optional byte-order mask, {
@code
 StdIn}

 *  will have an extra character {
@code
 \}{
@code
 uFEFF} at the beginning.

 *  

 *  Reference. 

 *  For additional documentation,

 *  see Section 1.5 of   

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 *  
@author
 David Pritchard

 */

public
 
final
 
class
 
StdIn
 
{

    
/*** begin: section (1 of 2) of code duplicated from In to StdIn. */

    

    
// assume Unicode UTF-8 encoding

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with System.out.

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// the default token separator; we maintain the invariant that this value

    
// is held by the scanner’s delimiter between calls

    
private
 
static
 
final
 
Pattern
 WHITESPACE_PATTERN 
=
 
Pattern
.
compile
(
“\\p{javaWhitespace}+”
);

    
// makes whitespace significant

    
private
 
static
 
final
 
Pattern
 EMPTY_PATTERN 
=
 
Pattern
.
compile
(
“”
);

    
// used to read the entire input

    
private
 
static
 
final
 
Pattern
 EVERYTHING_PATTERN 
=
 
Pattern
.
compile
(
“\\A”
);

    
/*** end: section (1 of 2) of code duplicated from In to StdIn. */

    
private
 
static
 
Scanner
 scanner
;

 

    
// it doesn’t make sense to instantiate this class

    
private
 
StdIn
()
 
{
 
}

    
//// begin: section (2 of 2) of code duplicated from In to StdIn,

    
//// with all methods changed from “public” to “public static”

   
/**

     * Returns true if standard input is empty (except possibly for whitespace).

     * Use this method to know whether the next call to {
@link
 #readString()}, 

     * {
@link
 #readDouble()}, etc will succeed.

     *

     * 
@return
 {
@code
 true} if standard input is empty (except possibly

     *         for whitespace); {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 isEmpty
()
 
{

        
return
 
!
scanner
.
hasNext
();

    
}

   
/**

     * Returns true if standard input has a next line.

     * Use this method to know whether the

     * next call to {
@link
 #readLine()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextChar()}.

     *

     * 
@return
 {
@code
 true} if standard input has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 hasNextLine
()
 
{

        
return
 scanner
.
hasNextLine
();

    
}

    
/**

     * Returns true if standard input has more input (including whitespace).

     * Use this method to know whether the next call to {
@link
 #readChar()} will succeed.

     * This method is functionally equivalent to {
@link
 #hasNextLine()}.

     *

     * 
@return
 {
@code
 true} if standard input has more input (including whitespace);

     *         {
@code
 false} otherwise

     */

    
public
 
static
 
boolean
 hasNextChar
()
 
{

        scanner
.
useDelimiter
(
EMPTY_PATTERN
);

        
boolean
 result 
=
 scanner
.
hasNext
();

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

        
return
 result
;

    
}

   
/**

     * Reads and returns the next line, excluding the line separator if present.

     *

     * 
@return
 the next line, excluding the line separator if present;

     *         {
@code
 null} if no such line

     */

    
public
 
static
 
String
 readLine
()
 
{

        
String
 line
;

        
try
 
{

            line 
=
 scanner
.
nextLine
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            line 
=
 
null
;

        
}

        
return
 line
;

    
}

    
/**

     * Reads and returns the next character.

     *

     * 
@return
 the next {
@code
 char}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
char
 readChar
()
 
{

        
try
 
{

            scanner
.
useDelimiter
(
EMPTY_PATTERN
);

            
String
 ch 
=
 scanner
.
next
();

            
assert
 ch
.
length
()
 
==
 
1
 
:
 
“Internal (Std)In.readChar() error!”

                
+
 
” Please contact the authors.”
;

            scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);

            
return
 ch
.
charAt
(
0
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘char’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}
  

   
/**

     * Reads and returns the remainder of the input, as a string.

     *

     * 
@return
 the remainder of the input, as a string

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
String
 readAll
()
 
{

        
if
 
(
!
scanner
.
hasNextLine
())

            
return
 
“”
;

        
String
 result 
=
 scanner
.
useDelimiter
(
EVERYTHING_PATTERN
).
next
();

        
// not that important to reset delimeter, since now scanner is empty

        scanner
.
useDelimiter
(
WHITESPACE_PATTERN
);
 
// but let’s do it anyway

        
return
 result
;

    
}

   
/**

     * Reads the next token  and returns the {
@code
 String}.

     *

     * 
@return
 the next {
@code
 String}

     * 
@throws
 NoSuchElementException if standard input is empty

     */

    
public
 
static
 
String
 readString
()
 
{

        
try
 
{

            
return
 scanner
.
next
();

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘String’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as an integer, and returns the integer.

     *

     * 
@return
 the next integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as an {
@code
 int}

     */

    
public
 
static
 
int
 readInt
()
 
{

        
try
 
{

            
return
 scanner
.
nextInt
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read an ‘int’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attemps to read an ‘int’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a double, and returns the double.

     *

     * 
@return
 the next double on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 double}

     */

    
public
 
static
 
double
 readDouble
()
 
{

        
try
 
{

            
return
 scanner
.
nextDouble
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘double’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘double’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a float, and returns the float.

     *

     * 
@return
 the next float on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 float}

     */

    
public
 
static
 
float
 readFloat
()
 
{

        
try
 
{

            
return
 scanner
.
nextFloat
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘float’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘float’ value from standard input, ”

                                           
+
 
“but there no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a long integer, and returns the long integer.

     *

     * 
@return
 the next long integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 long}

     */

    
public
 
static
 
long
 readLong
()
 
{

        
try
 
{

            
return
 scanner
.
nextLong
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘long’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘long’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a short integer, and returns the short integer.

     *

     * 
@return
 the next short integer on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 short}

     */

    
public
 
static
 
short
 readShort
()
 
{

        
try
 
{

            
return
 scanner
.
nextShort
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘short’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘short’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

   
/**

     * Reads the next token from standard input, parses it as a byte, and returns the byte.

     *

     * 
@return
 the next byte on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 byte}

     */

    
public
 
static
 
byte
 readByte
()
 
{

        
try
 
{

            
return
 scanner
.
nextByte
();

        
}

        
catch
 
(
InputMismatchException
 e
)
 
{

            
String
 token 
=
 scanner
.
next
();

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘byte’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘byte’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads the next token from standard input, parses it as a boolean,

     * and returns the boolean.

     *

     * 
@return
 the next boolean on standard input

     * 
@throws
 NoSuchElementException if standard input is empty

     * 
@throws
 InputMismatchException if the next token cannot be parsed as a {
@code
 boolean}:

     *    {
@code
 true} or {
@code
 1} for true, and {
@code
 false} or {
@code
 0} for false,

     *    ignoring case

     */

    
public
 
static
 
boolean
 readBoolean
()
 
{

        
try
 
{

            
String
 token 
=
 readString
();

            
if
 
(
“true”
.
equalsIgnoreCase
(
token
))
  
return
 
true
;

            
if
 
(
“false”
.
equalsIgnoreCase
(
token
))
 
return
 
false
;

            
if
 
(
“1”
.
equals
(
token
))
               
return
 
true
;

            
if
 
(
“0”
.
equals
(
token
))
               
return
 
false
;

            
throw
 
new
 
InputMismatchException
(
“attempts to read a ‘boolean’ value from standard input, ”

                                           
+
 
“but the next token is \””
 
+
 token 
+
 
“\””
);

        
}

        
catch
 
(
NoSuchElementException
 e
)
 
{

            
throw
 
new
 
NoSuchElementException
(
“attempts to read a ‘boolean’ value from standard input, ”

                                           
+
 
“but no more tokens are available”
);

        
}

    
}

    
/**

     * Reads all remaining tokens from standard input and returns them as an array of strings.

     *

     * 
@return
 all remaining tokens on standard input, as an array of strings

     */

    
public
 
static
 
String
[]
 readAllStrings
()
 
{

        
// we could use readAll.trim().split(), but that’s not consistent

        
// because trim() uses characters 0x00..0x20 as whitespace

        
String
[]
 tokens 
=
 WHITESPACE_PATTERN
.
split
(
readAll
());

        
if
 
(
tokens
.
length 
==
 
0
 
||
 tokens
[
0
].
length
()
 
>
 
0
)

            
return
 tokens
;

        
// don’t include first token if it is leading whitespace

        
String
[]
 decapitokens 
=
 
new
 
String
[
tokens
.
length

1
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  tokens . length  -   1 ;  i ++ )             decapitokens [ i ]   =  tokens [ i + 1 ];          return  decapitokens ;      }      /**      * Reads all remaining lines from standard input and returns them as an array of strings.      *  @return  all remaining lines on standard input, as an array of strings      */      public   static   String []  readAllLines ()   {          ArrayList < String >
 lines 
=
 
new
 
ArrayList
< String >
();

        
while
 
(
hasNextLine
())
 
{

            lines
.
add
(
readLine
());

        
}

        
return
 lines
.
toArray
(
new
 
String
[
lines
.
size
()]);

    
}

    
/**

     * Reads all remaining tokens from standard input, parses them as integers, and returns

     * them as an array of integers.

     * 
@return
 all remaining integers on standard input, as an array

     * 
@throws
 InputMismatchException if any token cannot be parsed as an {
@code
 int}

     */

    
public
 
static
 
int
[]
 readAllInts
()
 
{

        
String
[]
 fields 
=
 readAllStrings
();

        
int
[]
 vals 
=
 
new
 
int
[
fields
.
length
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  fields . length ;  i ++ )             vals [ i ]   =   Integer . parseInt ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from standard input, parses them as longs, and returns      * them as an array of longs.      *  @return  all remaining longs on standard input, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  long}      */      public   static   long []  readAllLongs ()   {          String []  fields  =  readAllStrings ();          long []  vals  =   new   long [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Long . parseLong ( fields [ i ]);          return  vals ;      }      /**      * Reads all remaining tokens from standard input, parses them as doubles, and returns      * them as an array of doubles.      *  @return  all remaining doubles on standard input, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}      */      public   static   double []  readAllDoubles ()   {          String []  fields  =  readAllStrings ();          double []  vals  =   new   double [ fields . length ];          for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )             vals [ i ]   =   Double . parseDouble ( fields [ i ]);          return  vals ;      }           //// end: section (2 of 2) of code duplicated from In to StdIn                // do this once when StdIn is initialized      static   {         resync ();      }      /**      * If StdIn changes, use this to reinitialize the scanner.      */      private   static   void  resync ()   {         setScanner ( new   Scanner ( new  java . io . BufferedInputStream ( System . in ),  CHARSET_NAME ));      }           private   static   void  setScanner ( Scanner  scanner )   {          StdIn . scanner  =  scanner ;          StdIn . scanner . useLocale ( LOCALE );      }     /**      * Reads all remaining tokens, parses them as integers, and returns      * them as an array of integers.      *  @return  all remaining integers, as an array      *  @throws  InputMismatchException if any token cannot be parsed as an { @code  int}      *  @deprecated  Replaced by { @link  #readAllInts()}.      */     @ Deprecated      public   static   int []  readInts ()   {          return  readAllInts ();      }     /**      * Reads all remaining tokens, parses them as doubles, and returns      * them as an array of doubles.      *  @return  all remaining doubles, as an array      *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}      *  @deprecated  Replaced by { @link  #readAllDoubles()}.      */     @ Deprecated      public   static   double []  readDoubles ()   {          return  readAllDoubles ();      }     /**      * Reads all remaining tokens and returns them as an array of strings.      *  @return  all remaining tokens, as an array of strings      *  @deprecated  Replaced by { @link  #readAllStrings()}.      */     @ Deprecated      public   static   String []  readStrings ()   {          return  readAllStrings ();      }      /**      * Interactive test of basic functionality.      *      *  @param  args the command-line arguments      */      public   static   void  main ( String []  args )   {          StdOut . print ( "Type a string: " );          String  s  =   StdIn . readString ();          StdOut . println ( "Your string was: "   +  s );          StdOut . println ();          StdOut . print ( "Type an int: " );          int  a  =   StdIn . readInt ();          StdOut . println ( "Your int was: "   +  a );          StdOut . println ();          StdOut . print ( "Type a boolean: " );          boolean  b  =   StdIn . readBoolean ();          StdOut . println ( "Your boolean was: "   +  b );          StdOut . println ();          StdOut . print ( "Type a double: " );          double  c  =   StdIn . readDouble ();          StdOut . println ( "Your double was: "   +  c );          StdOut . println ();      } } StdInTest.java StdInTest.java /**  * Test client for StdIn and In.   **/ import  java . util . Scanner ; import  java . lang . reflect . Array ; import  java . lang . reflect . Method ; import  java . io . ByteArrayInputStream ; public   class   StdInTest   {      private   static   boolean  testStdIn ;      private   static   Method  resyncMethod ;      private   static   int  testCount  =   0 ;           // make a printable/readable version of an object      public   static   Object  escape ( Object  original )   {          if   ( original  instanceof   Character )   {              char  u  =   ( char )   (( Character )  original );              int  idx  =   "\b\t\n\f\r\"\'\\" . indexOf ( u );              if   ( idx  >=
 
0
)

                
return
 
“\\”
+
“btnfr\”\’\\”
.
charAt
(
idx
);

            
if
 
(

<   32 )                    return   "\\" + Integer . toOctalString ( u );              if   ( u  >
 
126
)
 

                
return
 
“\\u”
 
+
 
String
.
format
(
“%04X”
,
 
(
int
)
 u
);

            
return
 original
;

        
}

        
else
 
if
 
(
original 
instanceof
 
String
)
 
{

            
StringBuilder
 result 
=
 
new
 
StringBuilder
();

            
for
 
(
char
 c 
:
 
((
String
)
 original
).
toCharArray
())

                result
.
append
(
escape
(
c
));

            
return
 
“\””
 
+
 result
.
toString
()
 
+
 
“\””
;

        
}

        
else
 
if
 
(
original
.
getClass
().
isArray
())
 
{

            
StringBuilder
 result 
=
 
new
 
StringBuilder
(
“[”
);

            
int
 len 
=
 
Array
.
getLength
(
original
);

            
for
 
(
int
 i 
=
 
0
;
 i 
<  len ;  i ++ )                 result . append ( " " ). append ( escape ( Array . get ( original ,  i )));              return  result . append ( "]" ). toString ();          }          return  original ;      }           public   static   boolean  canResync ()   {          try   {             resyncMethod  =   StdIn . class . getMethod ( "resync" );          }          catch   ( NoSuchMethodException  e )   {              return   false ;          }          return   true ;      }           /**      * In the two methods below, each Object[] of "steps" is a length-2      * array: the first is a String holding a method name, the second      * is the expected return value when that method is called in sequence.      */      public   static   void  test ( String  input ,   Object [][]  steps )   {         test ( input ,  steps ,   false );   // create Scanner from String          if   ( testStdIn )             test ( input ,  steps ,   true );    // uses stdIn/System.setIn         testCount ++ ;      }           public   static   void  test ( String  input ,   Object [][]  steps ,   boolean  useStdIn )   {          In  in  =   null ;          if   ( useStdIn )   {              try   {                  System . setIn ( new   ByteArrayInputStream ( input . getBytes ( "UTF-8" )));              }              catch   ( java . io . UnsupportedEncodingException  e )   {                  throw   new   RuntimeException ( e . toString ());              }              // in order for this to work, you need to change resync to public                           try   {   //call StdIn.resync();                 resyncMethod . invoke ( null );              }              catch   ( IllegalAccessException  e )   {                  throw   new   RuntimeException ( e . toString ());              }              catch   ( java . lang . reflect . InvocationTargetException  e )   {                  throw   new   RuntimeException ( e . toString ());                                  }          }          else               in  =   new   In ( new   Scanner ( input ));          int  count  =   0 ;          for   ( Object []  step  :  steps )   {              String  cmd  =   ( String )  step [ 0 ];              Object  expected  =  step [ 1 ];              Object  result ;                           String  preamble  =   "Failed input %s\nStep %d (%s)\n" ;              try   {                  Method  method ;                  // nice and easy since these methods take no arguments                  if   ( useStdIn )                     method  =   StdIn . class . getMethod ( cmd );                  else                     method  =  in . getClass (). getMethod ( cmd );                 result  =  method . invoke ( in );   // fine to be null for static              }              catch   ( NoSuchMethodException  e )   {                 java . io . StringWriter  errors  =   new  java . io . StringWriter ();                 e . printStackTrace ( new  java . io . PrintWriter ( errors ));                  throw   new   RuntimeException ( String . format ( preamble ,                                                            input ,  count ,  cmd )   +                                            errors . toString ());              }              catch   ( IllegalAccessException  e )   {                 java . io . StringWriter  errors  =   new  java . io . StringWriter ();                 e . printStackTrace ( new  java . io . PrintWriter ( errors ));                  throw   new   RuntimeException ( String . format ( preamble ,                                                            input ,  count ,  cmd )   +                                            errors . toString ());              }              catch   ( java . lang . reflect . InvocationTargetException  e )   {                 java . io . StringWriter  errors  =   new  java . io . StringWriter ();                 e . printStackTrace ( new  java . io . PrintWriter ( errors ));                 e . getCause (). printStackTrace ( new  java . io . PrintWriter ( errors ));                  throw   new   RuntimeException ( String . format ( preamble ,                                                            input ,  count ,  cmd )   +                                            errors . toString ());              }                                       if   ( expected . getClass (). isArray ())   {                  if   ( ! ( result . getClass (). isArray ()))   {                      StdOut . printf ( preamble  +   "Expected array, got %s\n" ,                                   input ,  count ,  cmd ,  result );                      continue ;                  }                  Object  r  =  result ,  e  =  expected ;   // to shorten lines below                  int  rl  =   Array . getLength ( r );                  int  el  =   Array . getLength ( e );                  if   ( el  !=  rl )                      StdOut . printf ( preamble  +   "Expected %d, got %d items:\n%s\n" ,                                   escape ( input ),  count ,  cmd ,  el ,  rl ,  escape ( r ));                  else   {                      for   ( int  i  =   0 ;  i  <  rl ;  i ++ )   {                          if   ( ! ( Array . get ( r ,  i ). equals ( Array . get ( e ,  i ))))                            StdOut . printf ( preamble  +   "\nExpected [%d]=%s, got %s\n" ,                                       escape ( input ),  count ,  cmd ,  i ,                                         escape ( Array . get ( e ,  i )),                                         escape ( Array . get ( r ,  i )));                      }                  }              }              else   if   ( ! result . equals ( expected ))   {                  StdOut . printf ( preamble  +   "Expected %s, got %s\n" ,                               escape ( input ),  count ,  cmd ,  escape ( expected ),                                 escape ( result ));              }             count ++ ;          }      }           public   static   void  main ( String []  args )   {         testStdIn  =  canResync ();                   if   ( testStdIn )                StdOut . println ( "Note: any errors appear duplicated since tests run 2x." );          else                StdOut . println ( "Note: StdIn.resync is private, only In will be tested." );         test ( "this is a test" ,                 new   Object [][]   {              { "isEmpty" ,   false },   { "hasNextChar" ,   true },   { "hasNextLine" ,   true },              { "readAllStrings" ,   new   String []   { "this" ,   "is" ,   "a" ,   "test" }},              { "isEmpty" ,   true },   { "hasNextChar" ,   false },   { "hasNextLine" ,   false }          });         test ( "\n\n\n" ,                 new   Object [][]   {              { "isEmpty" ,   true },   { "hasNextChar" ,   true },   { "hasNextLine" ,   true },              { "readAll" ,   "\n\n\n" }          });         test ( "" ,                 new   Object [][]   {              { "isEmpty" ,   true },   { "hasNextChar" ,   false },   { "hasNextLine" ,   false }          });         test ( "\t\t  \t\t" ,                 new   Object [][]   {              { "isEmpty" ,   true },   { "hasNextChar" ,   true },   { "hasNextLine" ,   true },              { "readAll" ,   "\t\t  \t\t" }          });         test ( "readLine consumes newline\nyeah!" ,                 new   Object [][]   {              { "readLine" ,   "readLine consumes newline" },   { "readChar" ,   'y' }          });         test ( "readString doesn't consume spaces" ,                 new   Object [][]   {              { "readString" ,   "readString" },   { "readChar" ,   ' ' }          });         test ( "\n\nblank lines test" ,               new   Object [][]   {              { "readLine" ,   "" },   { "readLine" ,   "" },   { "hasNextLine" ,   true },              { "readLine" ,   "blank lines test" },   { "hasNextLine" ,   false }          });         test ( "   \n  \t \n  correct  \n\t\n\t .trim replacement \n\t" ,               new   Object [][]   {              { "readAllStrings" ,   new   String []{ "correct" ,   ".trim" ,   "replacement" }},              { "hasNextChar" ,   false }          });          StringBuilder  sb  =   new   StringBuilder ();          Object [][]  expected  =   new   Object [ 2000 ][ 2 ];          for   ( int  i = 0 ;  i  <   1000 ;  i ++ )   {             sb . append (( char )  i );             sb . append (( char )   ( i  +   8000 ));   // include weird non-breaking spaces             expected [ 2 * i ][ 0 ]   =   "readChar" ;             expected [ 2 * i + 1 ][ 0 ]   =   "readChar" ;             expected [ 2 * i ][ 1 ]   =   ( char ) i ;             expected [ 2 * i + 1 ][ 1 ]   =   ( char )( i + 8000 );          }         test ( sb . toString (),  expected );         test ( " this \n and \that \n " ,               new   Object [][]   {              { "readString" ,   "this" },   { "readString" ,   "and" },   { "readChar" ,   ' ' },              { "readString" ,   "hat" },   { "readChar" ,   ' ' },   { "isEmpty" ,   true },              { "hasNextLine" ,   true },   { "readLine" ,   "" },   { "readLine" ,   " " }          });         test ( " 1 2 3 \n\t 4 5 " ,               new   Object [][]   {              { "readAllInts" ,   new   int []   { 1 ,   2 ,   3 ,   4 ,   5 }}          });         test ( " 0 1 False true falsE True " ,               new   Object [][]   {              { "readBoolean" ,   false },   { "readBoolean" ,   true },                { "readBoolean" ,   false },   { "readBoolean" ,   true },                { "readBoolean" ,   false },   { "readBoolean" ,   true }          });         test ( " \240\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008"                   +   "\u2009\u200A\u205F\u3000" ,               new   Object [][]   {              { "readString" ,   "\240" },     // non-breaking space - not java whitespace              { "readString" ,   "\u2007" },   // similarly              { "hasNextChar" ,   true },   // there is some stuff left over              { "isEmpty" ,   true },          // but it is all whitespace              { "readChar" ,   '\u2008' }      // such as this one          });                   // line sep, par sep, NEL, unit sep, vtab --- first 3 are newlines          // NB: \205 is treated as a line separator, but not whitespace!         test ( "a\u2028b\u2029c\37d\13e\205f" ,                 new   Object [][]   {              { "readAllStrings" ,   new   String []{ "a" ,   "b" ,   "c" ,   "d" ,   "e\205f" }}          });         test ( "a\u2028b\u2029c\37d\13e\205f" ,                 new   Object [][]   {              { "readLine" ,   "a" },              { "readLine" ,   "b" },              { "readLine" ,   "c\37d\13e" },              { "readLine" ,   "f" }          });         test ( "\u2028\u2029" ,   // line separator, par separator               new   Object [][]   {              { "readLine" ,   "" },   { "hasNextLine" ,   true },   { "hasNextChar" ,   true },              { "readLine" ,   "" },   { "hasNextLine" ,   false },   { "hasNextChar" ,   false }          });         test ( "\n\n" ,                 new   Object [][]   {              { "readLine" ,   "" },   { "hasNextLine" ,   true },   { "hasNextChar" ,   true },              { "readLine" ,   "" },   { "hasNextLine" ,   false },   { "hasNextChar" ,   false }          });         test ( "\r\n\r\n" ,                 new   Object [][]   {              { "readLine" ,   "" },   { "hasNextLine" ,   true },   { "hasNextChar" ,   true },              { "readLine" ,   "" },   { "hasNextLine" ,   false },   { "hasNextChar" ,   false }          });         test ( "\n\r" ,                 new   Object [][]   {              { "readLine" ,   "" },   { "hasNextLine" ,   true },   { "hasNextChar" ,   true },              { "readLine" ,   "" },   { "hasNextLine" ,   false },   { "hasNextChar" ,   false }          });         test ( "\r\n" ,                 new   Object [][]   {              { "readLine" ,   "" },   { "hasNextChar" ,   false },   { "hasNextLine" ,   false }          });         test ( "3E4 \t -0.5 \n \t +4" ,                 new   Object [][]   {              { "readAllDoubles" ,   new   double []   { 30000 ,   - 0.5 ,   4 }}          });         test ( " whitespace " ,                 new   Object [][]   {              { "readString" ,   "whitespace" },   { "readChar" ,   ' ' },              { "hasNextLine" ,   false }          });         test ( " whitespace \n" ,                 new   Object [][]   {              { "readString" ,   "whitespace" },   { "readChar" ,   ' ' },              { "readLine" ,   "" },   { "hasNextLine" ,   false }          });         test ( " whitespace \n " ,                 new   Object [][]   {              { "readString" ,   "whitespace" },   { "readChar" ,   ' ' },              { "readLine" ,   "" },   { "hasNextLine" ,   true },              { "readLine" ,   " " },   { "hasNextLine" ,   false }          });         test ( " 34 -12983   3.25\n\t foo!" ,               new   Object [][]   {              { "readByte" ,   ( byte )   34 },                { "readShort" ,   ( short )   - 12983 },              { "readDouble" ,   3.25 },              { "readAll" ,   "\n\t foo!" }          });         test ( "30000000000  3.5 3e4, foo   \t\t ya" ,               new   Object [][]   {              { "readLong" ,   30000000000L },              { "readFloat" ,   ( float )   3.5 },              { "readAllStrings" ,   new   String []   { "3e4," ,   "foo" ,   "ya" }}          });          // testing consistency of whitespace and read(All)String(s)         test ( " \u0001 foo \u0001 foo \u0001 foo" ,               new   Object [][]   {              { "readAllStrings" ,   new   String []   {                  "\u0001" ,   "foo" ,   "\u0001" ,   "foo" ,   "\u0001" ,   "foo" }}          });         test ( " \u2005 foo \u2005 foo \u2005 foo" ,               new   Object [][]   {              { "readAllStrings" ,   new   String []   { "foo" ,   "foo" ,   "foo" }}          });         test ( " \u0001 foo \u0001 foo \u0001 foo" ,               new   Object [][]   {              { "readString" ,   "\u0001" },   { "readString" ,   "foo" },              { "readString" ,   "\u0001" },   { "readString" ,   "foo" },              { "readString" ,   "\u0001" },   { "readString" ,   "foo" }          });         test ( " \u2005 foo \u2005 foo \u2005 foo" ,               new   Object [][]   {              { "readString" ,   "foo" },   { "readString" ,   "foo" },   { "readString" ,   "foo" }          });          StdOut . printf ( "Ran %d tests.\n" ,  testCount );      } } StdOut.java StdOut.java /******************************************************************************  *  Compilation:  javac StdOut.java  *  Execution:    java StdOut  *  Dependencies: none  *  *  Writes data of various types to standard output.  *  ******************************************************************************/ import  java . io . OutputStreamWriter ; import  java . io . PrintWriter ; import  java . io . UnsupportedEncodingException ; import  java . util . Locale ; /**  *  This class provides methods for printing strings and numbers to standard output.  *  

 *  Getting started.

 *  To use this class, you must have {
@code
 StdOut.class} in your

 *  Java classpath. If you used our autoinstaller, you should be all set.

 *  Otherwise, either download

 *  stdlib.jar

 *  and add to your Java classpath or download

 *  StdOut.java

 *  and put a copy in your working directory.

 *  

 *  Here is an example program that uses {
@code
 StdOut}:

 *  


 *   public class TestStdOut {

 *       public static void main(String[] args) {

 *           int a = 17;

 *           int b = 23;

 *           int sum = a + b;

 *           StdOut.println("Hello, World");

 *           StdOut.printf("%d + %d = %d\n", a, b, sum);

 *       }

 *   }

 *  

 *  

 *  Differences with System.out.

 *  The behavior of {
@code
 StdOut} is similar to that of {
@link
 System#out},

 *  but there are a few technical differences:

 *  

     *  

  •  {
    @code
     StdOut} coerces the character-set encoding to UTF-8,

     *       which is a standard character encoding for Unicode.

     *  

  •  {
    @code
     StdOut} coerces the locale to {
    @link
     Locale#US},

     *       for consistency with {
    @link
     StdIn}, {
    @link
     Double#parseDouble(String)},

     *       and floating-point literals.

     *  

  •  {
    @code
     StdOut} flushes standard output after each call to

     *       {
    @code
     print()} so that text will appear immediately in the terminal.

     *  

 *  

 *  Reference.

 *  For additional documentation,

 *  see Section 1.5 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdOut
 
{

    
// force Unicode UTF-8 encoding; otherwise it’s system dependent

    
private
 
static
 
final
 
String
 CHARSET_NAME 
=
 
“UTF-8”
;

    
// assume language = English, country = US for consistency with StdIn

    
private
 
static
 
final
 
Locale
 LOCALE 
=
 
Locale
.
US
;

    
// send output here

    
private
 
static
 
PrintWriter
 out
;

    
// this is called before invoking any methods

    
static
 
{

        
try
 
{

            out 
=
 
new
 
PrintWriter
(
new
 
OutputStreamWriter
(
System
.
out
,
 CHARSET_NAME
),
 
true
);

        
}

        
catch
 
(
UnsupportedEncodingException
 e
)
 
{

            
System
.
out
.
println
(
e
);

        
}

    
}

    
// don’t instantiate

    
private
 
StdOut
()
 
{
 
}

   
/**

     * Terminates the current line by printing the line-separator string.

     */

    
public
 
static
 
void
 println
()
 
{

        out
.
println
();

    
}

   
/**

     * Prints an object to this output stream and then terminates the line.

     *

     * 
@param
 x the object to print

     */

    
public
 
static
 
void
 println
(
Object
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a boolean to standard output and then terminates the line.

     *

     * 
@param
 x the boolean to print

     */

    
public
 
static
 
void
 println
(
boolean
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a character to standard output and then terminates the line.

     *

     * 
@param
 x the character to print

     */

    
public
 
static
 
void
 println
(
char
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a double to standard output and then terminates the line.

     *

     * 
@param
 x the double to print

     */

    
public
 
static
 
void
 println
(
double
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to standard output and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 println
(
float
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints an integer to standard output and then terminates the line.

     *

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 println
(
int
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a long to standard output and then terminates the line.

     *

     * 
@param
 x the long to print

     */

    
public
 
static
 
void
 println
(
long
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a short integer to standard output and then terminates the line.

     *

     * 
@param
 x the short to print

     */

    
public
 
static
 
void
 println
(
short
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Prints a byte to standard output and then terminates the line.

     * 

     * To write binary data, see {
@link
 BinaryStdOut}.

     *

     * 
@param
 x the byte to print

     */

    
public
 
static
 
void
 println
(
byte
 x
)
 
{

        out
.
println
(
x
);

    
}

   
/**

     * Flushes standard output.

     */

    
public
 
static
 
void
 print
()
 
{

        out
.
flush
();

    
}

   
/**

     * Prints an object to standard output and flushes standard output.

     * 

     * 
@param
 x the object to print

     */

    
public
 
static
 
void
 print
(
Object
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a boolean to standard output and flushes standard output.

     * 

     * 
@param
 x the boolean to print

     */

    
public
 
static
 
void
 print
(
boolean
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a character to standard output and flushes standard output.

     * 

     * 
@param
 x the character to print

     */

    
public
 
static
 
void
 print
(
char
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a double to standard output and flushes standard output.

     * 

     * 
@param
 x the double to print

     */

    
public
 
static
 
void
 print
(
double
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a float to standard output and flushes standard output.

     * 

     * 
@param
 x the float to print

     */

    
public
 
static
 
void
 print
(
float
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints an integer to standard output and flushes standard output.

     * 

     * 
@param
 x the integer to print

     */

    
public
 
static
 
void
 print
(
int
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a long integer to standard output and flushes standard output.

     * 

     * 
@param
 x the long integer to print

     */

    
public
 
static
 
void
 print
(
long
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a short integer to standard output and flushes standard output.

     * 

     * 
@param
 x the short integer to print

     */

    
public
 
static
 
void
 print
(
short
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a byte to standard output and flushes standard output.

     *

     * 
@param
 x the byte to print

     */

    
public
 
static
 
void
 print
(
byte
 x
)
 
{

        out
.
print
(
x
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to standard output, using the specified format

     * string and arguments, and then flushes standard output.

     *

     *

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
static
 
void
 printf
(
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
LOCALE
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Prints a formatted string to standard output, using the locale and

     * the specified format string and arguments; then flushes standard output.

     *

     * 
@param
 locale the locale

     * 
@param
 format the format string

     * 
@param
 args   the arguments accompanying the format string

     */

    
public
 
static
 
void
 printf
(
Locale
 locale
,
 
String
 format
,
 
Object

 args
)
 
{

        out
.
printf
(
locale
,
 format
,
 args
);

        out
.
flush
();

    
}

   
/**

     * Unit tests some of the methods in {
@code
 StdOut}.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
// write to stdout

        
StdOut
.
println
(
“Test”
);

        
StdOut
.
println
(
17
);

        
StdOut
.
println
(
true
);

        
StdOut
.
printf
(
“%.6f\n”
,
 
1.0
/
7.0
);

    
}

}

StdRandom.java
StdRandom.java
/******************************************************************************

 *  Compilation:  javac StdRandom.java

 *  Execution:    java StdRandom

 *  Dependencies: StdOut.java

 *

 *  A library of static methods to generate pseudo-random numbers from

 *  different distributions (bernoulli, uniform, gaussian, discrete,

 *  and exponential). Also includes a method for shuffling an array.

 *

 *

 *  %  java StdRandom 5

 *  seed = 1316600602069

 *  59 16.81826  true 8.83954  0 

 *  32 91.32098  true 9.11026  0 

 *  35 10.11874  true 8.95396  3 

 *  92 32.88401  true 8.87089  0 

 *  72 92.55791  true 9.46241  0 

 *

 *  % java StdRandom 5

 *  seed = 1316600616575

 *  96 60.17070  true 8.72821  0 

 *  79 32.01607  true 8.58159  0 

 *  81 59.49065  true 9.10423  1 

 *  96 51.65818  true 9.02102  0 

 *  99 17.55771  true 8.99762  0 

 *

 *  % java StdRandom 5 1316600616575

 *  seed = 1316600616575

 *  96 60.17070  true 8.72821  0 

 *  79 32.01607  true 8.58159  0 

 *  81 59.49065  true 9.10423  1 

 *  96 51.65818  true 9.02102  0 

 *  99 17.55771  true 8.99762  0 

 *

 *

 *  Remark

 *  ——

 *    – Relies on randomness of nextDouble() method in java.util.Random

 *      to generate pseudo-random numbers in [0, 1).

 *

 *    – This library allows you to set and get the pseudo-random number seed.

 *

 *    – See http://www.honeylocust.com/RngPack/ for an industrial

 *      strength random number generator in Java.

 *

 ******************************************************************************/

import
 java
.
util
.
Random
;

/**

 *  The {
@code
 StdRandom} class provides static methods for generating

 *  random number from various discrete and continuous distributions, 

 *  including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto,

 *  Poisson, and Cauchy. It also provides method for shuffling an

 *  array or subarray and generating random permutations.

 *  

 *  By convention, all intervals are half open. For example,

 *  uniform(-1.0, 1.0) returns a random number between

 *  -1.0 (inclusive) and 1.0 (exclusive).

 *  Similarly, shuffle(a, lo, hi) shuffles the hi - lo

 *  elements in the array a[], starting at index lo

 *  (inclusive) and ending at index hi (exclusive).

 *  

 *  For additional documentation,

 *  see Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdRandom
 
{

    
private
 
static
 
Random
 random
;
    
// pseudo-random number generator

    
private
 
static
 
long
 seed
;
        
// pseudo-random number generator seed

    
// static initializer

    
static
 
{

        
// this is how the seed was set in Java 1.4

        seed 
=
 
System
.
currentTimeMillis
();

        random 
=
 
new
 
Random
(
seed
);

    
}

    
// don’t instantiate

    
private
 
StdRandom
()
 
{
 
}

    
/**

     * Sets the seed of the pseudo-random number generator.

     * This method enables you to produce the same sequence of “random”

     * number for each execution of the program.

     * Ordinarily, you should call this method at most once per program.

     *

     * 
@param
 s the seed

     */

    
public
 
static
 
void
 setSeed
(
long
 s
)
 
{

        seed   
=
 s
;

        random 
=
 
new
 
Random
(
seed
);

    
}

    
/**

     * Returns the seed of the pseudo-random number generator.

     *

     * 
@return
 the seed

     */

    
public
 
static
 
long
 getSeed
()
 
{

        
return
 seed
;

    
}

    
/**

     * Returns a random real number uniformly in [0, 1).

     *

     * 
@return
 a random real number uniformly in [0, 1)

     */

    
public
 
static
 
double
 uniform
()
 
{

        
return
 random
.
nextDouble
();

    
}

    
/**

     * Returns a random integer uniformly in [0, n).

     * 

     * 
@param
 n number of possible integers

     * 
@return
 a random integer uniformly between 0 (inclusive) and {
@code
 n} (exclusive)

     * 
@throws
 IllegalArgumentException if {
@code
 n <= 0}      */      public   static   int  uniform ( int  n )   {          if   ( n  <=   0 )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );          return  random . nextInt ( n );      }      /**      * Returns a random long integer uniformly in [0, n).      *       *  @param  n number of possible { @code  long} integers      *  @return  a random long integer uniformly between 0 (inclusive) and { @code  n} (exclusive)      *  @throws  IllegalArgumentException if { @code  n <= 0}      */      public   static   long  uniform ( long  n )   {          if   ( n  <=   0L )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );          // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-          long  r  =  random . nextLong ();          long  m  =  n  -   1 ;          // power of two          if   (( n  &  m )   ==   0L )   {              return  r  &  m ;          }          // reject over-represented candidates          long  u  =  r  >>>
 
1
;

        
while
 
(

+
 m 

 
(

=
 u 
%
 n
)
 
<   0L )   {             u  =  random . nextLong ()   >>>
 
1
;

        
}

        
return
 r
;

    
}

    
///////////////////////////////////////////////////////////////////////////

    
//  STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA

    
//  THE STATIC METHODS ABOVE.

    
///////////////////////////////////////////////////////////////////////////

    
/**

     * Returns a random real number uniformly in [0, 1).

     * 

     * 
@return
     a random real number uniformly in [0, 1)

     * 
@deprecated
 Replaced by {
@link
 #uniform()}.

     */

    @
Deprecated

    
public
 
static
 
double
 random
()
 
{

        
return
 uniform
();

    
}

    
/**

     * Returns a random integer uniformly in [a, b).

     * 

     * 
@param
  a the left endpoint

     * 
@param
  b the right endpoint

     * 
@return
 a random integer uniformly in [a, b)

     * 
@throws
 IllegalArgumentException if {
@code
 b <= a}      *  @throws  IllegalArgumentException if { @code  b - a >= Integer.MAX_VALUE}

     */

    
public
 
static
 
int
 uniform
(
int
 a
,
 
int
 b
)
 
{

        
if
 
((

<=  a )   ||   (( long )  b  -  a  >=
 
Integer
.
MAX_VALUE
))
 
{

            
throw
 
new
 
IllegalArgumentException
(
“invalid range: [”
 
+
 a 
+
 
“, ”
 
+
 b 
+
 
“)”
);

        
}

        
return
 a 
+
 uniform
(


 a
);

    
}

    
/**

     * Returns a random real number uniformly in [a, b).

     * 

     * 
@param
  a the left endpoint

     * 
@param
  b the right endpoint

     * 
@return
 a random real number uniformly in [a, b)

     * 
@throws
 IllegalArgumentException unless {
@code
 a < b}      */      public   static   double  uniform ( double  a ,   double  b )   {          if   ( ! ( a  <  b ))   {              throw   new   IllegalArgumentException ( "invalid range: ["   +  a  +   ", "   +  b  +   ")" );          }          return  a  +  uniform ()   *   ( b - a );      }      /**      * Returns a random boolean from a Bernoulli distribution with success      * probability p.

     *

     * 
@param
  p the probability of returning {
@code
 true}

     * 
@return
 {
@code
 true} with probability {
@code
 p} and

     *         {
@code
 false} with probability {
@code
 1 – p}

     * 
@throws
 IllegalArgumentException unless {
@code
 0} ≤ {
@code
 p} ≤ {
@code
 1.0}

     */

    
public
 
static
 
boolean
 bernoulli
(
double
 p
)
 
{

        
if
 
(
!
(

>=
 
0.0
 
&&
 p 
<=   1.0 ))              throw   new   IllegalArgumentException ( "probability p must be between 0.0 and 1.0: "   +  p );          return  uniform ()   <  p ;      }      /**      * Returns a random boolean from a Bernoulli distribution with success      * probability 1/2.      *       *  @return  { @code  true} with probability 1/2 and      *         { @code  false} with probability 1/2      */      public   static   boolean  bernoulli ()   {          return  bernoulli ( 0.5 );      }      /**      * Returns a random real number from a standard Gaussian distribution.      *       *  @return  a random real number from a standard Gaussian distribution      *         (mean 0 and standard deviation 1).      */      public   static   double  gaussian ()   {          // use the polar form of the Box-Muller transform          double  r ,  x ,  y ;          do   {             x  =  uniform ( - 1.0 ,   1.0 );             y  =  uniform ( - 1.0 ,   1.0 );             r  =  x * x  +  y * y ;          }   while   ( r  >=
 
1
 
||
 r 
==
 
0
);

        
return
 x 
*
 
Math
.
sqrt
(

2
 
*
 
Math
.
log
(
r
)
 
/
 r
);

        
// Remark:  y * Math.sqrt(-2 * Math.log(r) / r)

        
// is an independent random gaussian

    
}

    
/**

     * Returns a random real number from a Gaussian distribution with mean μ

     * and standard deviation σ.

     * 

     * 
@param
  mu the mean

     * 
@param
  sigma the standard deviation

     * 
@return
 a real number distributed according to the Gaussian distribution

     *         with mean {
@code
 mu} and standard deviation {
@code
 sigma}

     */

    
public
 
static
 
double
 gaussian
(
double
 mu
,
 
double
 sigma
)
 
{

        
return
 mu 
+
 sigma 
*
 gaussian
();

    
}

    
/**

     * Returns a random integer from a geometric distribution with success

     * probability p.

     * The integer represents the number of independent trials

     * before the first success.

     * 

     * 
@param
  p the parameter of the geometric distribution

     * 
@return
 a random integer from a geometric distribution with success

     *         probability {
@code
 p}; or {
@code
 Integer.MAX_VALUE} if

     *         {
@code
 p} is (nearly) equal to {
@code
 1.0}.

     * 
@throws
 IllegalArgumentException unless {
@code
 p >= 0.0} and {
@code
 p <= 1.0}      */      public   static   int  geometric ( double  p )   {          if   ( ! ( p  >=
 
0
))
 
{

            
throw
 
new
 
IllegalArgumentException
(
“probability p must be greater than 0: ”
 
+
 p
);

        
}

        
if
 
(
!
(

<=   1.0 ))   {              throw   new   IllegalArgumentException ( "probability p must not be larger than 1: "   +  p );          }          // using algorithm given by Knuth          return   ( int )   Math . ceil ( Math . log ( uniform ())   /   Math . log ( 1.0   -  p ));      }      /**      * Returns a random integer from a Poisson distribution with mean λ.      *      *  @param   lambda the mean of the Poisson distribution      *  @return  a random integer from a Poisson distribution with mean { @code  lambda}      *  @throws  IllegalArgumentException unless { @code  lambda > 0.0} and not infinite

     */

    
public
 
static
 
int
 poisson
(
double
 lambda
)
 
{

        
if
 
(
!
(
lambda 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must be positive: ”
 
+
 lambda
);

        
if
 
(
Double
.
isInfinite
(
lambda
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must not be infinite: ”
 
+
 lambda
);

        
// using algorithm given by Knuth

        
// see http://en.wikipedia.org/wiki/Poisson_distribution

        
int
 k 
=
 
0
;

        
double
 p 
=
 
1.0
;

        
double
 expLambda 
=
 
Math
.
exp
(

lambda
);

        
do
 
{

            k
++
;

            p 
*=
 uniform
();

        
}
 
while
 
(

>=
 expLambda
);

        
return
 k

1
;

    
}

    
/**

     * Returns a random real number from the standard Pareto distribution.

     *

     * 
@return
 a random real number from the standard Pareto distribution

     */

    
public
 
static
 
double
 pareto
()
 
{

        
return
 pareto
(
1.0
);

    
}

    
/**

     * Returns a random real number from a Pareto distribution with

     * shape parameter α.

     *

     * 
@param
  alpha shape parameter

     * 
@return
 a random real number from a Pareto distribution with shape

     *         parameter {
@code
 alpha}

     * 
@throws
 IllegalArgumentException unless {
@code
 alpha > 0.0}

     */

    
public
 
static
 
double
 pareto
(
double
 alpha
)
 
{

        
if
 
(
!
(
alpha 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“alpha must be positive: ”
 
+
 alpha
);

        
return
 
Math
.
pow
(
1
 

 uniform
(),
 

1.0
/
alpha
)
 

 
1.0
;

    
}

    
/**

     * Returns a random real number from the Cauchy distribution.

     *

     * 
@return
 a random real number from the Cauchy distribution.

     */

    
public
 
static
 
double
 cauchy
()
 
{

        
return
 
Math
.
tan
(
Math
.
PI 
*
 
(
uniform
()
 

 
0.5
));

    
}

    
/**

     * Returns a random integer from the specified discrete distribution.

     *

     * 
@param
  probabilities the probability of occurrence of each integer

     * 
@return
 a random integer from a discrete distribution:

     *         {
@code
 i} with probability {
@code
 probabilities[i]}

     * 
@throws
 IllegalArgumentException if {
@code
 probabilities} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if sum of array entries is not (very nearly) equal to {
@code
 1.0}

     * 
@throws
 IllegalArgumentException unless {
@code
 probabilities[i] >= 0.0} for each index {
@code
 i}

     */

    
public
 
static
 
int
 discrete
(
double
[]
 probabilities
)
 
{

        
if
 
(
probabilities 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument array is null”
);

        
double
 EPSILON 
=
 
1.0E-14
;

        
double
 sum 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  probabilities . length ;  i ++ )   {              if   ( ! ( probabilities [ i ]   >=
 
0.0
))

                
throw
 
new
 
IllegalArgumentException
(
“array entry ”
 
+
 i 
+
 
” must be nonnegative: ”
 
+
 probabilities
[
i
]);

            sum 
+=
 probabilities
[
i
];

        
}

        
if
 
(
sum 
>
 
1.0
 
+
 EPSILON 
||
 sum 
<   1.0   -  EPSILON )              throw   new   IllegalArgumentException ( "sum of array entries does not approximately equal 1.0: "   +  sum );          // the for loop may not return a value when both r is (nearly) 1.0 and when the          // cumulative sum is less than 1.0 (as a result of floating-point roundoff error)          while   ( true )   {              double  r  =  uniform ();             sum  =   0.0 ;              for   ( int  i  =   0 ;  i  <  probabilities . length ;  i ++ )   {                 sum  =  sum  +  probabilities [ i ];                  if   ( sum  >
 r
)
 
return
 i
;

            
}

        
}

    
}

    
/**

     * Returns a random integer from the specified discrete distribution.

     *

     * 
@param
  frequencies the frequency of occurrence of each integer

     * 
@return
 a random integer from a discrete distribution:

     *         {
@code
 i} with probability proportional to {
@code
 frequencies[i]}

     * 
@throws
 IllegalArgumentException if {
@code
 frequencies} is {
@code
 null}

     * 
@throws
 IllegalArgumentException if all array entries are {
@code
 0}

     * 
@throws
 IllegalArgumentException if {
@code
 frequencies[i]} is negative for any index {
@code
 i}

     * 
@throws
 IllegalArgumentException if sum of frequencies exceeds {
@code
 Integer.MAX_VALUE} (231 – 1)

     */

    
public
 
static
 
int
 discrete
(
int
[]
 frequencies
)
 
{

        
if
 
(
frequencies 
==
 
null
)
 
throw
 
new
 
IllegalArgumentException
(
“argument array is null”
);

        
long
 sum 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  frequencies . length ;  i ++ )   {              if   ( frequencies [ i ]   <   0 )                  throw   new   IllegalArgumentException ( "array entry "   +  i  +   " must be nonnegative: "   +  frequencies [ i ]);             sum  +=  frequencies [ i ];          }          if   ( sum  ==   0 )              throw   new   IllegalArgumentException ( "at least one array entry must be positive" );          if   ( sum  >=
 
Integer
.
MAX_VALUE
)

            
throw
 
new
 
IllegalArgumentException
(
“sum of frequencies overflows an int”
);

        
// pick index i with probabilitity proportional to frequency

        
double
 r 
=
 uniform
((
int
)
 sum
);

        sum 
=
 
0
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  frequencies . length ;  i ++ )   {             sum  +=  frequencies [ i ];              if   ( sum  >
 r
)
 
return
 i
;

        
}

        
// can’t reach here

        
assert
 
false
;

        
return
 

1
;

    
}

    
/**

     * Returns a random real number from an exponential distribution

     * with rate λ.

     * 

     * 
@param
  lambda the rate of the exponential distribution

     * 
@return
 a random real number from an exponential distribution with

     *         rate {
@code
 lambda}

     * 
@throws
 IllegalArgumentException unless {
@code
 lambda > 0.0}

     */

    
public
 
static
 
double
 exp
(
double
 lambda
)
 
{

        
if
 
(
!
(
lambda 
>
 
0.0
))

            
throw
 
new
 
IllegalArgumentException
(
“lambda must be positive: ”
 
+
 lambda
);

        
return
 

Math
.
log
(
1
 

 uniform
())
 
/
 lambda
;

    
}

    
/**

     * Rearranges the elements of the specified array in uniformly random order.

     *

     * 
@param
  a the array to shuffle

     * 
@throws
 IllegalArgumentException if {
@code
 a} is {
@code
 null}

     */

    
public
 
static
 
void
 shuffle
(
Object
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              Object  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( double []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              double  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( int []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              int  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified array in uniformly random order.      *      *  @param   a the array to shuffle      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      */      public   static   void  shuffle ( char []  a )   {         validateNotNull ( a );          int  n  =  a . length ;          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              int  r  =  i  +  uniform ( n - i );       // between i and n-1              char  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      *       */      public   static   void  shuffle ( Object []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              Object  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   void  shuffle ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              double  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Rearranges the elements of the specified subarray in uniformly random order.      *      *  @param   a the array to shuffle      *  @param   lo the left endpoint (inclusive)      *  @param   hi the right endpoint (exclusive)      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}      *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   void  shuffle ( int []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              int  r  =  i  +  uniform ( hi - i );       // between i and hi-1              int  temp  =  a [ i ];             a [ i ]   =  a [ r ];             a [ r ]   =  temp ;          }      }      /**      * Returns a uniformly random permutation of n elements.

     *

     * 
@param
  n number of elements

     * 
@throws
 IllegalArgumentException if {
@code
 n} is negative

     * 
@return
 an array of length {
@code
 n} that is a uniformly random permutation

     *         of {
@code
 0}, {
@code
 1}, …, {
@code
 n-1}

     */

    
public
 
static
 
int
[]
 permutation
(
int
 n
)
 
{

        
if
 
(

<   0 )   throw   new   IllegalArgumentException ( "argument is negative" );          int []  perm  =   new   int [ n ];          for   ( int  i  =   0 ;  i  <  n ;  i ++ )             perm [ i ]   =  i ;         shuffle ( perm );          return  perm ;      }      /**      * Returns a uniformly random permutation of k of n elements.

     *

     * 
@param
  n number of elements

     * 
@param
  k number of elements to select

     * 
@throws
 IllegalArgumentException if {
@code
 n} is negative

     * 
@throws
 IllegalArgumentException unless {
@code
 0 <= k <= n}      *  @return  an array of length { @code  k} that is a uniformly random permutation      *         of { @code  k} of the elements from { @code  0}, { @code  1}, ..., { @code  n-1}      */      public   static   int []  permutation ( int  n ,   int  k )   {          if   ( n  <   0 )   throw   new   IllegalArgumentException ( "argument is negative" );          if   ( k  <   0   ||  k  >
 n
)
 
throw
 
new
 
IllegalArgumentException
(
“k must be between 0 and n”
);

        
int
[]
 perm 
=
 
new
 
int
[
k
];

        
for
 
(
int
 i 
=
 
0
;
 i 
<  k ;  i ++ )   {              int  r  =  uniform ( i + 1 );      // between 0 and i             perm [ i ]   =  perm [ r ];             perm [ r ]   =  i ;          }          for   ( int  i  =  k ;  i  <  n ;  i ++ )   {              int  r  =  uniform ( i + 1 );      // between 0 and i              if   ( r  <  k )  perm [ r ]   =  i ;          }          return  perm ;      }      // throw an IllegalArgumentException if x is null      // (x can be of type Object[], double[], int[], ...)      private   static   void  validateNotNull ( Object  x )   {          if   ( x  ==   null )   {              throw   new   IllegalArgumentException ( "argument is null" );          }      }      // throw an exception unless 0 <= lo <= hi <= length      private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {          if   ( lo  <   0   ||  hi  >
 length 
||
 lo 
>
 hi
)
 
{

            
throw
 
new
 
IllegalArgumentException
(
“subarray indices out of bounds: [”
 
+
 lo 
+
 
“, ”
 
+
 hi 
+
 
“)”
);

        
}

    
}

    
/**

     * Unit tests the methods in this class.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
if
 
(
args
.
length 
==
 
2
)
 
StdRandom
.
setSeed
(
Long
.
parseLong
(
args
[
1
]));

        
double
[]
 probabilities 
=
 
{
 
0.5
,
 
0.3
,
 
0.1
,
 
0.1
 
};

        
int
[]
 frequencies 
=
 
{
 
5
,
 
3
,
 
1
,
 
1
 
};

        
String
[]
 a 
=
 
“A B C D E F G”
.
split
(
” ”
);

        
StdOut
.
println
(
“seed = ”
 
+
 
StdRandom
.
getSeed
());

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              StdOut . printf ( "%2d " ,    uniform ( 100 ));              StdOut . printf ( "%8.5f " ,  uniform ( 10.0 ,   99.0 ));              StdOut . printf ( "%5b " ,    bernoulli ( 0.5 ));              StdOut . printf ( "%7.5f " ,  gaussian ( 9.0 ,   0.2 ));              StdOut . printf ( "%1d " ,    discrete ( probabilities ));              StdOut . printf ( "%1d " ,    discrete ( frequencies ));              StdOut . printf ( "%11d " ,   uniform ( 100000000000L ));              StdRandom . shuffle ( a );              for   ( String  s  :  a )                  StdOut . print ( s );              StdOut . println ();          }      } } StdStats.java StdStats.java /******************************************************************************  *  Compilation:  javac StdStats.java  *  Execution:    java StdStats < input.txt  *  Dependencies: StdOut.java  *  *  Library of statistical functions.  *  *  The test client reads an array of real numbers from standard  *  input, and computes the minimum, mean, maximum, and  *  standard deviation.  *  *  The functions all throw a java.lang.IllegalArgumentException  *  if the array passed in as an argument is null.  *  *  The floating-point functions all return NaN if any input is NaN.  *  *  Unlike Math.min() and Math.max(), the min() and max() functions  *  do not differentiate between -0.0 and 0.0.  *  *  % more tiny.txt  *  5  *  3.0 1.0 2.0 5.0 4.0  *  *  % java StdStats < tiny.txt  *         min   1.000  *        mean   3.000  *         max   5.000  *     std dev   1.581  *  *  Should these funtions use varargs instead of array arguments?  *  ******************************************************************************/ /**  *  The { @code  StdStats} class provides static methods for computing  *  statistics such as min, max, mean, sample standard deviation, and  *  sample variance.  *  

 *  For additional documentation, see

 *  Section 2.2 of

 *  Computer Science: An Interdisciplinary Approach

 *  by Robert Sedgewick and Kevin Wayne.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
final
 
class
 
StdStats
 
{

    
private
 
StdStats
()
 
{
 
}

    
/**

     * Returns the maximum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the maximum value in the array {
@code
 a[]};

     *         {
@code
 Double.NEGATIVE_INFINITY} if no such value

     */

    
public
 
static
 
double
 max
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
double
 max 
=
 
Double
.
NEGATIVE_INFINITY
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the maximum value in the specified subarray.

     *

     * 
@param
  a the array

     * 
@param
  lo the left endpoint of the subarray (inclusive)

     * 
@param
  hi the right endpoint of the subarray (exclusive)

     * 
@return
 the maximum value in the subarray {
@code
 a[lo..hi)};

     *         {
@code
 Double.NEGATIVE_INFINITY} if no such value

     * 
@throws
 IllegalArgumentException if {
@code
 a} is {
@code
 null}

     * 
@throws
 IllegalArgumentException unless {
@code
 (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  max ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  max  =   Double . NEGATIVE_INFINITY ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the maximum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the maximum value in the array {
@code
 a[]};

     *         {
@code
 Integer.MIN_VALUE} if no such value

     */

    
public
 
static
 
int
 max
(
int
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 max 
=
 
Integer
.
MIN_VALUE
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( a [ i ]   >
 max
)
 max 
=
 a
[
i
];

        
}

        
return
 max
;

    
}

    
/**

     * Returns the minimum value in the specified array.

     *

     * 
@param
  a the array

     * 
@return
 the minimum value in the array {
@code
 a[]};

     *         {
@code
 Double.POSITIVE_INFINITY} if no such value

     */

    
public
 
static
 
double
 min
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
double
 min 
=
 
Double
.
POSITIVE_INFINITY
;

        
for
 
(
int
 i 
=
 
0
;
 i 
<  a . length ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the minimum value in the specified subarray.      *      *  @param   a the array      *  @param   lo the left endpoint of the subarray (inclusive)      *  @param   hi the right endpoint of the subarray (exclusive)      *  @return  the maximum value in the subarray { @code  a[lo..hi)};      *         { @code  Double.POSITIVE_INFINITY} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  min ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  min  =   Double . POSITIVE_INFINITY ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {              if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the minimum value in the specified array.      *      *  @param   a the array      *  @return  the minimum value in the array { @code  a[]};      *         { @code  Integer.MAX_VALUE} if no such value      */      public   static   int  min ( int []  a )   {         validateNotNull ( a );          int  min  =   Integer . MAX_VALUE ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {              if   ( a [ i ]   <  min )  min  =  a [ i ];          }          return  min ;      }      /**      * Returns the average value in the specified array.      *      *  @param   a the array      *  @return  the average value in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  mean ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  sum  =  sum ( a );          return  sum  /  a . length ;      }      /**      * Returns the average value in the specified subarray.      *      *  @param  a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the average value in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  mean ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  sum  =  sum ( a ,  lo ,  hi );          return  sum  /  length ;      }      /**      * Returns the average value in the specified array.      *      *  @param   a the array      *  @return  the average value in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  mean ( int []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          int  sum  =  sum ( a );          return   1.0   *  sum  /  a . length ;      }      /**      * Returns the sample variance in the specified array.      *      *  @param   a the array      *  @return  the sample variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  var ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( a . length  -   1 );      }      /**      * Returns the sample variance in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sample variance in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  var ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a ,  lo ,  hi );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( length  -   1 );      }      /**      * Returns the sample variance in the specified array.      *      *  @param   a the array      *  @return  the sample variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  var ( int []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /   ( a . length  -   1 );      }      /**      * Returns the population variance in the specified array.      *      *  @param   a the array      *  @return  the population variance in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  varp ( double []  a )   {         validateNotNull ( a );          if   ( a . length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /  a . length ;      }      /**      * Returns the population variance in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the population variance in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  varp ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          int  length  =  hi  -  lo ;          if   ( length  ==   0 )   return   Double . NaN ;          double  avg  =  mean ( a ,  lo ,  hi );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );          }          return  sum  /  length ;      }      /**      * Returns the sample standard deviation in the specified array.      *      *  @param   a the array      *  @return  the sample standard deviation in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  stddev ( double []  a )   {         validateNotNull ( a );          return   Math . sqrt ( var ( a ));      }      /**      * Returns the sample standard deviation in the specified array.      *      *  @param   a the array      *  @return  the sample standard deviation in the array { @code  a[]};      *         { @code  Double.NaN} if no such value      */      public   static   double  stddev ( int []  a )   {         validateNotNull ( a );          return   Math . sqrt ( var ( a ));      }      /**      * Returns the sample standard deviation in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sample standard deviation in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  stddev ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          return   Math . sqrt ( var ( a ,  lo ,  hi ));      }      /**      * Returns the population standard deviation in the specified array.      *      *  @param   a the array      *  @return  the population standard deviation in the array;      *         { @code  Double.NaN} if no such value      */      public   static   double  stddevp ( double []  a )   {         validateNotNull ( a );          return   Math . sqrt ( varp ( a ));      }      /**      * Returns the population standard deviation in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the population standard deviation in the subarray { @code  a[lo..hi)};      *         { @code  Double.NaN} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      public   static   double  stddevp ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          return   Math . sqrt ( varp ( a ,  lo ,  hi ));      }      /**      * Returns the sum of all values in the specified array.      *      *  @param   a the array      *  @return  the sum of all values in the array { @code  a[]};      *         { @code  0.0} if no such value      */      private   static   double  sum ( double []  a )   {         validateNotNull ( a );          double  sum  =   0.0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }      /**      * Returns the sum of all values in the specified subarray.      *      *  @param   a the array      *  @param  lo the left endpoint of the subarray (inclusive)      *  @param  hi the right endpoint of the subarray (exclusive)      *  @return  the sum of all values in the subarray { @code  a[lo..hi)};      *         { @code  0.0} if no such value      *  @throws  IllegalArgumentException if { @code  a} is { @code  null}       *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}      */      private   static   double  sum ( double []  a ,   int  lo ,   int  hi )   {         validateNotNull ( a );         validateSubarrayIndices ( lo ,  hi ,  a . length );          double  sum  =   0.0 ;          for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }      /**      * Returns the sum of all values in the specified array.      *      *  @param   a the array      *  @return  the sum of all values in the array { @code  a[]};      *         { @code  0.0} if no such value      */      private   static   int  sum ( int []  a )   {         validateNotNull ( a );          int  sum  =   0 ;          for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {             sum  +=  a [ i ];          }          return  sum ;      }     /**      * Plots the points (0, a0), (1, a1), …,

     * (n-1, an-1) to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotPoints
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
StdDraw
.
setPenRadius
(
1.0
 
/
 
(
3.0
 
*
 n
));

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              StdDraw . point ( i ,  a [ i ]);          }      }     /**      * Plots the line segments connecting       * (iai) to

     * (i+1, ai+1) for 

     * each i to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotLines
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
StdDraw
.
setPenRadius
();

        
for
 
(
int
 i 
=
 
1
;
 i 
<  n ;  i ++ )   {              StdDraw . line ( i - 1 ,  a [ i - 1 ],  i ,  a [ i ]);          }      }     /**      * Plots bars from (0, ai) to

     * (ai) for each i

     * to standard draw.

     *

     * 
@param
 a the array of values

     */

    
public
 
static
 
void
 plotBars
(
double
[]
 a
)
 
{

        validateNotNull
(
a
);

        
int
 n 
=
 a
.
length
;

        
StdDraw
.
setXscale
(

1
,
 n
);

        
for
 
(
int
 i 
=
 
0
;
 i 
<  n ;  i ++ )   {              StdDraw . filledRectangle ( i ,  a [ i ] / 2 ,   0.25 ,  a [ i ] / 2 );          }      }      // throw an IllegalArgumentException if x is null      // (x is either of type double[] or int[])      private   static   void  validateNotNull ( Object  x )   {          if   ( x  ==   null )              throw   new   IllegalArgumentException ( "argument is null" );      }      // throw an exception unless 0 <= lo <= hi <= length      private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {          if   ( lo  <   0   ||  hi  >
 length 
||
 lo 
>
 hi
)

            
throw
 
new
 
IllegalArgumentException
(
“subarray indices out of bounds: [”
 
+
 lo 
+
 
“, ”
 
+
 hi 
+
 
“)”
);

    
}

   
/**

     * Unit tests {
@code
 StdStats}.

     * Convert command-line arguments to array of doubles and call various methods.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
double
[]
 a 
=
 
StdArrayIO
.
readDouble1D
();

        
StdOut
.
printf
(
”       min %10.3f\n”
,
 min
(
a
));

        
StdOut
.
printf
(
”      mean %10.3f\n”
,
 mean
(
a
));

        
StdOut
.
printf
(
”       max %10.3f\n”
,
 max
(
a
));

        
StdOut
.
printf
(
”    stddev %10.3f\n”
,
 stddev
(
a
));

        
StdOut
.
printf
(
”       var %10.3f\n”
,
 var
(
a
));

        
StdOut
.
printf
(
”   stddevp %10.3f\n”
,
 stddevp
(
a
));

        
StdOut
.
printf
(
”      varp %10.3f\n”
,
 varp
(
a
));

    
}

}

StopwatchCPU.java
StopwatchCPU.java
/******************************************************************************

 *  Compilation:  javac StopwatchCPU.java

 *  Execution:    none

 *  Dependencies: none

 *

 *  A version of Stopwatch.java that measures CPU time on a single

 *  core or processor (instead of wall clock time).

 *

 ******************************************************************************/

import
 java
.
lang
.
management
.
ThreadMXBean
;

import
 java
.
lang
.
management
.
ManagementFactory
;

/**

 *  The {
@code
 StopwatchCPU} data type is for measuring

 *  the CPU time used during a programming task.

 *

 *  See {
@link
 Stopwatch} for a version that measures wall-clock time

 *  (the real time that elapses).

 *

 *  
@author
 Josh Hug

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
StopwatchCPU
 
{

    
private
 
static
 
final
 
double
 NANOSECONDS_PER_SECOND 
=
 
1000000000
;

    
private
 
final
 
ThreadMXBean
 threadTimer
;

    
private
 
final
 
long
 start
;

            

    
/**

     * Initializes a new stopwatch.

     */

    
public
 
StopwatchCPU
()
 
{
  

        threadTimer 
=
 
ManagementFactory
.
getThreadMXBean
();

        start 
=
 threadTimer
.
getCurrentThreadCpuTime
();

    
}
   

        

    
/**

     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.

     *

     * 
@return
 elapsed CPU time (in seconds) since the stopwatch was created

     */

    
public
 
double
 elapsedTime
()
 
{

        
long
 now 
=
 threadTimer
.
getCurrentThreadCpuTime
();

        
return
 
(
now 

 start
)
 
/
 NANOSECONDS_PER_SECOND
;

    
}
   

}

Stopwatch.java
Stopwatch.java
/******************************************************************************

 *  Compilation:  javac Stopwatch.java

 *  Execution:    java Stopwatch n

 *  Dependencies: none

 *

 *  A utility class to measure the running time (wall clock) of a program.

 *

 *  % java8 Stopwatch 100000000

 *  6.666667e+11  0.5820 seconds

 *  6.666667e+11  8.4530 seconds

 *

 ******************************************************************************/

/**

 *  The {
@code
 Stopwatch} data type is for measuring

 *  the time that elapses between the start and end of a

 *  programming task (wall-clock time).

 *

 *  See {
@link
 StopwatchCPU} for a version that measures CPU time.

 *

 *  
@author
 Robert Sedgewick

 *  
@author
 Kevin Wayne

 */

public
 
class
 
Stopwatch
 
{
 

    
private
 
final
 
long
 start
;

    
/**

     * Initializes a new stopwatch.

     */

    
public
 
Stopwatch
()
 
{

        start 
=
 
System
.
currentTimeMillis
();

    
}
 

    
/**

     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.

     *

     * 
@return
 elapsed CPU time (in seconds) since the stopwatch was created

     */

    
public
 
double
 elapsedTime
()
 
{

        
long
 now 
=
 
System
.
currentTimeMillis
();

        
return
 
(
now 

 start
)
 
/
 
1000.0
;

    
}

    

    
/**

     * Unit tests the {
@code
 Stopwatch} data type.

     * Takes a command-line argument {
@code
 n} and computes the 

     * sum of the square roots of the first {
@code
 n} positive integers,

     * first using {
@code
 Math.sqrt()}, then using {
@code
 Math.pow()}.

     * It prints to standard output the sum and the amount of time to

     * compute the sum. Note that the discrete sum can be approximated by

     * an integral – the sum should be approximately 2/3 * (n^(3/2) – 1).

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
int
 n 
=
 
Integer
.
parseInt
(
args
[
0
]);

        
// sum of square roots of integers from 1 to n using Math.sqrt(x).

        
Stopwatch
 timer1 
=
 
new
 
Stopwatch
();

        
double
 sum1 
=
 
0.0
;

        
for
 
(
int
 i 
=
 
1
;
 i 
<=  n ;  i ++ )   {             sum1  +=   Math . sqrt ( i );          }          double  time1  =  timer1 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum1 ,  time1 );          // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).          Stopwatch  timer2  =   new   Stopwatch ();          double  sum2  =   0.0 ;          for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {             sum2  +=   Math . pow ( i ,   0.5 );          }          double  time2  =  timer2 . elapsedTime ();          StdOut . printf ( "%e (%.2f seconds)\n" ,  sum2 ,  time2 );      } }   TestIntroCS.java TestIntroCS.java /******************************************************************************  *  Compilation:  javac-introcs TestIntroCS.java  *  Execution:    java-introcs TestIntroCS n  *    *  Play chaos game to produce Barnsley's fern.  *  This program is intended to test that stdlib.jar is properly installed.  *  *  % java-introcs TestIntroCS 10000  *   ******************************************************************************/ public   class   TestIntroCS   {      public   static   void  main ( String []  args )   {          int  n  =   10000 ;    // number of points to draw (default 10000)          if   ( args . length  ==   1 )   {             n  =   Integer . parseInt ( args [ 0 ]);          }          StdDraw . setScale ( - 0.1 ,   1.1 );                // leave a 10% border          StdDraw . clear ( StdDraw . BOOK_LIGHT_BLUE );     // background color          StdDraw . setPenColor ( 0 ,   114 ,   0 );             // a shade of green          // starting point          double  x  =   0.5 ;          double  y  =   0.0 ;          // repeated choose one of four update rules at random          for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {              double  tempx ,  tempy ;              double  r  =   StdRandom . uniform ( 0.0 ,   1.0 );              // stem              if   ( r  <=   0.01 )    {                 tempx  =   0.50 ;                 tempy  =   0.16   *  y ;              }              // largest left-hand leaflet              else   if   ( r  <=   0.08 )   {                 tempx  =    0.20   *  x  -   0.26   *  y  +   0.400 ;                 tempy  =    0.23   *  x  +   0.22   *  y  -   0.045 ;              }              // largest right-hand leaflet              else   if   ( r  <=   0.15 )   {                 tempx  =   - 0.15   *  x  +   0.28   *  y  +   0.575 ;                 tempy  =    0.26   *  x  +   0.24   *  y  -   0.086 ;              }              // successively smaller leaflets              else   {                 tempx  =    0.85   *  x  +   0.04   *  y  +   0.075 ;                 tempy  =   - 0.04   *  x  +   0.85   *  y  +   0.180 ;              }              // update (x, y) and draw point             x  =  tempx ;             y  =  tempy ;              StdDraw . point ( x ,  y );          }      }     } UnicodeTest.java UnicodeTest.java /******************************************************************************  *  Compilation:  javac-introcs  UnicodeTest.java  *  Execution:    java-introcs  UnicodeTest  *  Dependencies: StdOut.java  *  *  This programs prints out all of the Unicode characters in the basic  *  multilingual plane (U+0000 to U+FFFF) in a table. It skips the  *  following types of characters:  *    -    *    -  control characters  *    -  modifier symbols  *    -  non-spacing marks  *    -  Unicode formatting commands  *    -  reserved for surrogate pairs  *    -  reserved for private use  *  *  *  % java-introcs UnicodeTest  *  U+0020      !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /    *  U+0030   0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  

 *  U+0040   @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  

 *  U+0050   P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]     _  

 *  U+0060      a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  

 *  U+0070   p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~     

 *  U+00A0      ¡  ¢  £  ¤  ¥  ¦  §     ©  ª  «  ¬     ®     

 *  U+00B0   °  ±  ²  ³     µ  ¶  ·     ¹  º  »  ¼  ½  ¾  ¿  

 *  U+00C0   À  Á  Â  Ã  Ä  Å  Æ  Ç  È  É  Ê  Ë  Ì  Í  Î  Ï  

 *  U+00D0   Ð  Ñ  Ò  Ó  Ô  Õ  Ö  ×  Ø  Ù  Ú  Û  Ü  Ý  Þ  ß  

 *  U+00E0   à  á  â  ã  ä  å  æ  ç  è  é  ê  ë  ì  í  î  ï  

 *  U+00F0   ð  ñ  ò  ó  ô  õ  ö  ÷  ø  ù  ú  û  ü  ý  þ  ÿ 

 *  U+0100   Ā  ā  Ă  ă  Ą  ą  Ć  ć  Ĉ  ĉ  Ċ  ċ  Č  č  Ď  ď

 *  …

 *

 *  Depending on your system setup and font, not all of the Unicode

 *  characters may display properly.

 *

 *  Quirks: when printing certain Hebrew or Arabic characters, the

 *  table may print right-to-left instead of left-to-right.

 *

 *  For a description of Unicode terminology, see:

 *  http://docs.oracle.com/javase/tutorial/i18n/text/terminology.html

 *

 *  For the Character API, see:

 *  http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html

 *

 *  To see what each Unicode character should look like, see:

 *  http://www.fileformat.info/info/unicode/index.htm

 *  http://www.fileformat.info/info/unicode/char/05D0/index.htm

 *

 *

 ******************************************************************************/

public
 
class
 
UnicodeTest
 
{

    
// number of Unicode characters to display per line

    
private
 
static
 
final
 
int
 CHARS_PER_LINE 
=
 
16
;

    
// number of Unicode characters to display (basic multilingual plane)

    
private
 
static
 
final
 
int
 MAX_CHAR 
=
 
65536
;

    
// do not instantiate

    
private
 
UnicodeTest
()
 
{
 
}

    
// Returns a string representation of the given codePoint, or a single

    
// space if the codePoint should not be suppressed when printing.

    
private
 
static
 
String
 toString
(
int
 codePoint
)
 
{

        
if
 
(
!
Character
.
isDefined
(
codePoint
))
             
return
 
” ”
;

        
if
 
(
Character
.
isISOControl
(
codePoint
))
           
return
 
” ”
;

        
if
 
(
Character
.
isWhitespace
(
codePoint
))
           
return
 
” ”
;

     
// if (Character.isSurrogate(codePoint)             return ” “;   // Java 1.7+ only

        
if
 
(
Character
.
isLowSurrogate
((
char
)
 codePoint
))
  
return
 
” ”
;
   
// Java 1.5+

        
if
 
(
Character
.
isHighSurrogate
((
char
)
 codePoint
))
 
return
 
” ”
;
   
// Java 1.5+

        
switch
(
Character
.
getType
(
codePoint
))
 
{

            
case
 
Character
.
MODIFIER_SYMBOL
:
              
return
 
” ”
;

            
case
 
Character
.
CONTROL
:
                      
return
 
” ”
;

            
case
 
Character
.
MODIFIER_LETTER
:
              
return
 
” ”
;

            
case
 
Character
.
NON_SPACING_MARK
:
             
return
 
” ”
;

            
case
 
Character
.
FORMAT
:
                       
return
 
” ”
;

            
case
 
Character
.
PRIVATE_USE
:
                  
return
 
” ”
;

            
default
:
 
return
 
new
 
String
(
Character
.
toChars
(
codePoint
));

        
}

    
}

   
/**

     * Prints Unicode characters to standard output.

     *

     * 
@param
 args the command-line arguments

     */

    
public
 
static
 
void
 main
(
String
[]
 args
)
 
{

        
for
 
(
int
 line 
=
 
0
;
 line 
<   2 * Character . MAX_VALUE  /  CHARS_PER_LINE ;  line ++ )   {              StringBuilder  buffer  =   new   StringBuilder ();              for   ( int  i  =   0 ;  i  <  CHARS_PER_LINE ;  i ++ )   {                  int  codePoint  =  CHARS_PER_LINE * line  +  i ;                 buffer . append ( toString ( codePoint )   +   "  " );              }              String  output  =  buffer . toString ();              if   ( ! output . trim (). equals ( "" ))   {                  // U+202D is the Unicode override to force left-to-right direction                  // but doesn't seem to work with Unix more                  StdOut . printf ( "U+%04X   %s\n" ,   16 * line ,  output );              }          }      } } BinaryIn.class public final synchronized class BinaryIn { private static final int EOF = -1; private java.io.BufferedInputStream in; private int buffer; private int n; public void BinaryIn(); public void BinaryIn(java.io.InputStream); public void BinaryIn(java.net.Socket); public void BinaryIn(java.net.URL); public void BinaryIn(String); private void fillBuffer(); public boolean exists(); public boolean isEmpty(); public boolean readBoolean(); public char readChar(); public char readChar(int); public String readString(); public short readShort(); public int readInt(); public int readInt(int); public long readLong(); public double readDouble(); public float readFloat(); public byte readByte(); public static void main(String[]); } BinaryOut.class public final synchronized class BinaryOut { private java.io.BufferedOutputStream out; private int buffer; private int n; public void BinaryOut(); public void BinaryOut(java.io.OutputStream); public void BinaryOut(String); public void BinaryOut(java.net.Socket); private void writeBit(boolean); private void writeByte(int); private void clearBuffer(); public void flush(); public void close(); public void write(boolean); public void write(byte); public void write(int); public void write(int, int); public void write(double); public void write(long); public void write(float); public void write(short); public void write(char); public void write(char, int); public void write(String); public void write(String, int); public static void main(String[]); static void ();
}

BinaryStdIn.class
public final synchronized class BinaryStdIn {
private static final int EOF = -1;
private static java.io.BufferedInputStream in;
private static int buffer;
private static int n;
private static boolean isInitialized;
private void BinaryStdIn();
private static void initialize();
private static void fillBuffer();
public static void close();
public static boolean isEmpty();
public static boolean readBoolean();
public static char readChar();
public static char readChar(int);
public static String readString();
public static short readShort();
public static int readInt();
public static int readInt(int);
public static long readLong();
public static double readDouble();
public static float readFloat();
public static byte readByte();
public static void main(String[]);
}

BinaryStdOut.class
public final synchronized class BinaryStdOut {
private static java.io.BufferedOutputStream out;
private static int buffer;
private static int n;
private static boolean isInitialized;
private void BinaryStdOut();
private static void initialize();
private static void writeBit(boolean);
private static void writeByte(int);
private static void clearBuffer();
public static void flush();
public static void close();
public static void write(boolean);
public static void write(byte);
public static void write(int);
public static void write(int, int);
public static void write(double);
public static void write(long);
public static void write(float);
public static void write(short);
public static void write(char);
public static void write(char, int);
public static void write(String);
public static void write(String, int);
public static void main(String[]);
static void ();
}

Draw.class
public final synchronized class Draw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
public static final java.awt.Color BLACK;
public static final java.awt.Color BLUE;
public static final java.awt.Color CYAN;
public static final java.awt.Color DARK_GRAY;
public static final java.awt.Color GRAY;
public static final java.awt.Color GREEN;
public static final java.awt.Color LIGHT_GRAY;
public static final java.awt.Color MAGENTA;
public static final java.awt.Color ORANGE;
public static final java.awt.Color PINK;
public static final java.awt.Color RED;
public static final java.awt.Color WHITE;
public static final java.awt.Color YELLOW;
public static final java.awt.Color BOOK_BLUE;
public static final java.awt.Color BOOK_LIGHT_BLUE;
public static final java.awt.Color BOOK_RED;
public static final java.awt.Color PRINCETON_ORANGE;
private static final java.awt.Color DEFAULT_PEN_COLOR;
private static final java.awt.Color DEFAULT_CLEAR_COLOR;
private static final double BORDER = 0.0;
private static final double DEFAULT_XMIN = 0.0;
private static final double DEFAULT_XMAX = 1.0;
private static final double DEFAULT_YMIN = 0.0;
private static final double DEFAULT_YMAX = 1.0;
private static final int DEFAULT_SIZE = 512;
private static final double DEFAULT_PEN_RADIUS = 0.002;
private static final java.awt.Font DEFAULT_FONT;
private java.awt.Color penColor;
private int width;
private int height;
private double penRadius;
private boolean defer;
private double xmin;
private double ymin;
private double xmax;
private double ymax;
private String name;
private final Object mouseLock;
private final Object keyLock;
private java.awt.Font font;
private javax.swing.JLabel draw;
private java.awt.image.BufferedImage offscreenImage;
private java.awt.image.BufferedImage onscreenImage;
private java.awt.Graphics2D offscreen;
private java.awt.Graphics2D onscreen;
private javax.swing.JFrame frame;
private boolean isMousePressed;
private double mouseX;
private double mouseY;
private final java.util.LinkedList keysTyped;
private final java.util.TreeSet keysDown;
private final java.util.ArrayList listeners;
public void Draw(String);
public void Draw();
private void init();
public void setLocationOnScreen(int, int);
public void setDefaultCloseOperation(int);
public void setCanvasSize(int, int);
private javax.swing.JMenuBar createMenuBar();
private static void validate(double, String);
private static void validateNonnegative(double, String);
private static void validateNotNull(Object, String);
public void setXscale();
public void setYscale();
public void setXscale(double, double);
public void setYscale(double, double);
private double scaleX(double);
private double scaleY(double);
private double factorX(double);
private double factorY(double);
private double userX(double);
private double userY(double);
public void clear();
public void clear(java.awt.Color);
public double getPenRadius();
public void setPenRadius();
public void setPenRadius(double);
public java.awt.Color getPenColor();
public void setPenColor();
public void setPenColor(java.awt.Color);
public void setPenColor(int, int, int);
public void xorOn();
public void xorOff();
public javax.swing.JLabel getJLabel();
public java.awt.Font getFont();
public void setFont();
public void setFont(java.awt.Font);
public void line(double, double, double, double);
private void pixel(double, double);
public void point(double, double);
public void circle(double, double, double);
public void filledCircle(double, double, double);
public void ellipse(double, double, double, double);
public void filledEllipse(double, double, double, double);
public void arc(double, double, double, double, double);
public void square(double, double, double);
public void filledSquare(double, double, double);
public void rectangle(double, double, double, double);
public void filledRectangle(double, double, double, double);
public void polygon(double[], double[]);
public void filledPolygon(double[], double[]);
private static java.awt.Image getImage(String);
public void picture(double, double, String);
public void picture(double, double, String, double);
public void picture(double, double, String, double, double);
public void picture(double, double, String, double, double, double);
public void text(double, double, String);
public void text(double, double, String, double);
public void textLeft(double, double, String);
public void textRight(double, double, String);
public void show(int);
public void pause(int);
public void show();
private void draw();
public void enableDoubleBuffering();
public void disableDoubleBuffering();
public void save(String);
public void actionPerformed(java.awt.event.ActionEvent);
public void addListener(DrawListener);
public boolean isMousePressed();
public boolean mousePressed();
public double mouseX();
public double mouseY();
public void mouseEntered(java.awt.event.MouseEvent);
public void mouseExited(java.awt.event.MouseEvent);
public void mousePressed(java.awt.event.MouseEvent);
public void mouseReleased(java.awt.event.MouseEvent);
public void mouseClicked(java.awt.event.MouseEvent);
public void mouseDragged(java.awt.event.MouseEvent);
public void mouseMoved(java.awt.event.MouseEvent);
public boolean hasNextKeyTyped();
public char nextKeyTyped();
public boolean isKeyPressed(int);
public void keyTyped(java.awt.event.KeyEvent);
public void keyPressed(java.awt.event.KeyEvent);
public void keyReleased(java.awt.event.KeyEvent);
public static void main(String[]);
static void ();
}

DrawListener.class
public abstract interface DrawListener {
public abstract void mousePressed(double, double);
public abstract void mouseDragged(double, double);
public abstract void mouseReleased(double, double);
public abstract void mouseClicked(double, double);
public abstract void keyTyped(char);
public abstract void keyPressed(int);
public abstract void keyReleased(int);
}

Draw$RetinaImageIcon.class
synchronized class Draw$RetinaImageIcon extends javax.swing.ImageIcon {
public void Draw$RetinaImageIcon(java.awt.Image);
public int getIconWidth();
public int getIconHeight();
public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

GrayscalePicture.class
public final synchronized class GrayscalePicture implements java.awt.event.ActionListener {
private java.awt.image.BufferedImage image;
private javax.swing.JFrame frame;
private String filename;
private boolean isOriginUpperLeft;
private final int width;
private final int height;
public void GrayscalePicture(int, int);
public void GrayscalePicture(GrayscalePicture);
public void GrayscalePicture(String);
private static java.awt.Color toGray(java.awt.Color);
public javax.swing.JLabel getJLabel();
public void setOriginUpperLeft();
public void setOriginLowerLeft();
public void show();
public int height();
public int width();
private void validateRowIndex(int);
private void validateColumnIndex(int);
private void validateGrayscaleValue(int);
public java.awt.Color get(int, int);
public int getGrayscale(int, int);
public void set(int, int, java.awt.Color);
public void setGrayscale(int, int, int);
public boolean equals(Object);
public String toString();
public int hashCode();
public void save(String);
public void save(java.io.File);
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
}

In.class
public final synchronized class In {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static final java.util.regex.Pattern WHITESPACE_PATTERN;
private static final java.util.regex.Pattern EMPTY_PATTERN;
private static final java.util.regex.Pattern EVERYTHING_PATTERN;
private java.util.Scanner scanner;
public void In();
public void In(java.net.Socket);
public void In(java.net.URL);
public void In(java.io.File);
public void In(String);
public void In(java.util.Scanner);
public boolean exists();
public boolean isEmpty();
public boolean hasNextLine();
public boolean hasNextChar();
public String readLine();
public char readChar();
public String readAll();
public String readString();
public int readInt();
public double readDouble();
public float readFloat();
public long readLong();
public short readShort();
public byte readByte();
public boolean readBoolean();
public String[] readAllStrings();
public String[] readAllLines();
public int[] readAllInts();
public long[] readAllLongs();
public double[] readAllDoubles();
public void close();
public static int[] readInts(String);
public static double[] readDoubles(String);
public static String[] readStrings(String);
public static int[] readInts();
public static double[] readDoubles();
public static String[] readStrings();
public static void main(String[]);
static void ();
}

Out.class
public synchronized class Out {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private java.io.PrintWriter out;
public void Out(java.io.OutputStream);
public void Out();
public void Out(java.net.Socket);
public void Out(String);
public void close();
public void println();
public void println(Object);
public void println(boolean);
public void println(char);
public void println(double);
public void println(float);
public void println(int);
public void println(long);
public void println(byte);
public void print();
public void print(Object);
public void print(boolean);
public void print(char);
public void print(double);
public void print(float);
public void print(int);
public void print(long);
public void print(byte);
public transient void printf(String, Object[]);
public transient void printf(java.util.Locale, String, Object[]);
public static void main(String[]);
static void ();
}

Picture.class
public final synchronized class Picture implements java.awt.event.ActionListener {
private java.awt.image.BufferedImage image;
private javax.swing.JFrame frame;
private String filename;
private boolean isOriginUpperLeft;
private final int width;
private final int height;
public void Picture(int, int);
public void Picture(Picture);
public void Picture(String);
public void Picture(java.io.File);
public javax.swing.JLabel getJLabel();
public void setOriginUpperLeft();
public void setOriginLowerLeft();
public void show();
public int height();
public int width();
private void validateRowIndex(int);
private void validateColumnIndex(int);
public java.awt.Color get(int, int);
public int getRGB(int, int);
public void set(int, int, java.awt.Color);
public void setRGB(int, int, int);
public boolean equals(Object);
public String toString();
public int hashCode();
public void save(String);
public void save(java.io.File);
public void actionPerformed(java.awt.event.ActionEvent);
public static void main(String[]);
}

PlayMusic$1.class
final synchronized class PlayMusic$1 implements Runnable {
void PlayMusic$1(String);
public void run();
}

PlayMusic.class
public synchronized class PlayMusic {
public void PlayMusic();
private static void playApplet(String);
public static synchronized void play(String);
private static void stream(String);
public static void main(String[]);
}

StdArrayIO.class
public synchronized class StdArrayIO {
private void StdArrayIO();
public static double[] readDouble1D();
public static void print(double[]);
public static double[][] readDouble2D();
public static void print(double[][]);
public static int[] readInt1D();
public static void print(int[]);
public static int[][] readInt2D();
public static void print(int[][]);
public static boolean[] readBoolean1D();
public static void print(boolean[]);
public static boolean[][] readBoolean2D();
public static void print(boolean[][]);
public static void main(String[]);
}

StdAudio$1.class
final synchronized class StdAudio$1 implements Runnable {
void StdAudio$1(String);
public void run();
}

StdAudio$2.class
final synchronized class StdAudio$2 implements Runnable {
void StdAudio$2();
public void run();
}

StdAudio.class
public final synchronized class StdAudio {
public static final int SAMPLE_RATE = 44100;
private static final int BYTES_PER_SAMPLE = 2;
private static final int BITS_PER_SAMPLE = 16;
private static final double MAX_16_BIT = 32768.0;
private static final int SAMPLE_BUFFER_SIZE = 4096;
private static final int MONO = 1;
private static final int STEREO = 2;
private static final boolean LITTLE_ENDIAN = 0;
private static final boolean BIG_ENDIAN = 1;
private static final boolean SIGNED = 1;
private static final boolean UNSIGNED = 0;
private static javax.sound.sampled.SourceDataLine line;
private static byte[] buffer;
private static int bufferSize;
private void StdAudio();
private static void init();
private static javax.sound.sampled.AudioInputStream getAudioInputStreamFromFile(String);
public static void close();
public static void play(double);
public static void play(double[]);
public static double[] read(String);
public static void save(String, double[]);
public static synchronized void play(String);
private static void stream(javax.sound.sampled.AudioInputStream);
public static synchronized void loop(String);
private static double[] note(double, double, double);
public static void main(String[]);
static void ();
}

StdDraw.class
public final synchronized class StdDraw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
public static final java.awt.Color BLACK;
public static final java.awt.Color BLUE;
public static final java.awt.Color CYAN;
public static final java.awt.Color DARK_GRAY;
public static final java.awt.Color GRAY;
public static final java.awt.Color GREEN;
public static final java.awt.Color LIGHT_GRAY;
public static final java.awt.Color MAGENTA;
public static final java.awt.Color ORANGE;
public static final java.awt.Color PINK;
public static final java.awt.Color RED;
public static final java.awt.Color WHITE;
public static final java.awt.Color YELLOW;
public static final java.awt.Color BOOK_BLUE;
public static final java.awt.Color BOOK_LIGHT_BLUE;
public static final java.awt.Color BOOK_RED;
public static final java.awt.Color PRINCETON_ORANGE;
private static final java.awt.Color DEFAULT_PEN_COLOR;
private static final java.awt.Color DEFAULT_CLEAR_COLOR;
private static java.awt.Color penColor;
private static final int DEFAULT_SIZE = 512;
private static int width;
private static int height;
private static final double DEFAULT_PEN_RADIUS = 0.002;
private static double penRadius;
private static boolean defer;
private static final double BORDER = 0.0;
private static final double DEFAULT_XMIN = 0.0;
private static final double DEFAULT_XMAX = 1.0;
private static final double DEFAULT_YMIN = 0.0;
private static final double DEFAULT_YMAX = 1.0;
private static double xmin;
private static double ymin;
private static double xmax;
private static double ymax;
private static Object mouseLock;
private static Object keyLock;
private static final java.awt.Font DEFAULT_FONT;
private static java.awt.Font font;
private static java.awt.image.BufferedImage offscreenImage;
private static java.awt.image.BufferedImage onscreenImage;
private static java.awt.Graphics2D offscreen;
private static java.awt.Graphics2D onscreen;
private static StdDraw std;
private static javax.swing.JFrame frame;
private static boolean isMousePressed;
private static double mouseX;
private static double mouseY;
private static java.util.LinkedList keysTyped;
private static java.util.TreeSet keysDown;
private void StdDraw();
public static void setCanvasSize();
public static void setCanvasSize(int, int);
private static void init();
private static javax.swing.JMenuBar createMenuBar();
private static void validate(double, String);
private static void validateNonnegative(double, String);
private static void validateNotNull(Object, String);
public static void setXscale();
public static void setYscale();
public static void setScale();
public static void setXscale(double, double);
public static void setYscale(double, double);
public static void setScale(double, double);
private static double scaleX(double);
private static double scaleY(double);
private static double factorX(double);
private static double factorY(double);
private static double userX(double);
private static double userY(double);
public static void clear();
public static void clear(java.awt.Color);
public static double getPenRadius();
public static void setPenRadius();
public static void setPenRadius(double);
public static java.awt.Color getPenColor();
public static void setPenColor();
public static void setPenColor(java.awt.Color);
public static void setPenColor(int, int, int);
public static java.awt.Font getFont();
public static void setFont();
public static void setFont(java.awt.Font);
public static void line(double, double, double, double);
private static void pixel(double, double);
public static void point(double, double);
public static void circle(double, double, double);
public static void filledCircle(double, double, double);
public static void ellipse(double, double, double, double);
public static void filledEllipse(double, double, double, double);
public static void arc(double, double, double, double, double);
public static void square(double, double, double);
public static void filledSquare(double, double, double);
public static void rectangle(double, double, double, double);
public static void filledRectangle(double, double, double, double);
public static void polygon(double[], double[]);
public static void filledPolygon(double[], double[]);
private static java.awt.Image getImage(String);
public static void picture(double, double, String);
public static void picture(double, double, String, double);
public static void picture(double, double, String, double, double);
public static void picture(double, double, String, double, double, double);
public static void text(double, double, String);
public static void text(double, double, String, double);
public static void textLeft(double, double, String);
public static void textRight(double, double, String);
public static void show(int);
public static void pause(int);
public static void show();
private static void draw();
public static void enableDoubleBuffering();
public static void disableDoubleBuffering();
public static void save(String);
public void actionPerformed(java.awt.event.ActionEvent);
public static boolean isMousePressed();
public static boolean mousePressed();
public static double mouseX();
public static double mouseY();
public void mouseClicked(java.awt.event.MouseEvent);
public void mouseEntered(java.awt.event.MouseEvent);
public void mouseExited(java.awt.event.MouseEvent);
public void mousePressed(java.awt.event.MouseEvent);
public void mouseReleased(java.awt.event.MouseEvent);
public void mouseDragged(java.awt.event.MouseEvent);
public void mouseMoved(java.awt.event.MouseEvent);
public static boolean hasNextKeyTyped();
public static char nextKeyTyped();
public static boolean isKeyPressed(int);
public void keyTyped(java.awt.event.KeyEvent);
public void keyPressed(java.awt.event.KeyEvent);
public void keyReleased(java.awt.event.KeyEvent);
public static void main(String[]);
static void ();
}

StdDraw$RetinaImageIcon.class
synchronized class StdDraw$RetinaImageIcon extends javax.swing.ImageIcon {
public void StdDraw$RetinaImageIcon(java.awt.Image);
public int getIconWidth();
public int getIconHeight();
public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

StdIn.class
public final synchronized class StdIn {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static final java.util.regex.Pattern WHITESPACE_PATTERN;
private static final java.util.regex.Pattern EMPTY_PATTERN;
private static final java.util.regex.Pattern EVERYTHING_PATTERN;
private static java.util.Scanner scanner;
private void StdIn();
public static boolean isEmpty();
public static boolean hasNextLine();
public static boolean hasNextChar();
public static String readLine();
public static char readChar();
public static String readAll();
public static String readString();
public static int readInt();
public static double readDouble();
public static float readFloat();
public static long readLong();
public static short readShort();
public static byte readByte();
public static boolean readBoolean();
public static String[] readAllStrings();
public static String[] readAllLines();
public static int[] readAllInts();
public static long[] readAllLongs();
public static double[] readAllDoubles();
private static void resync();
private static void setScanner(java.util.Scanner);
public static int[] readInts();
public static double[] readDoubles();
public static String[] readStrings();
public static void main(String[]);
static void ();
}

StdInTest.class
public synchronized class StdInTest {
private static boolean testStdIn;
private static reflect.Method resyncMethod;
private static int testCount;
public void StdInTest();
public static Object escape(Object);
public static boolean canResync();
public static void test(String, Object[][]);
public static void test(String, Object[][], boolean);
public static void main(String[]);
static void ();
}

StdOut.class
public final synchronized class StdOut {
private static final String CHARSET_NAME = UTF-8;
private static final java.util.Locale LOCALE;
private static java.io.PrintWriter out;
private void StdOut();
public static void println();
public static void println(Object);
public static void println(boolean);
public static void println(char);
public static void println(double);
public static void println(float);
public static void println(int);
public static void println(long);
public static void println(short);
public static void println(byte);
public static void print();
public static void print(Object);
public static void print(boolean);
public static void print(char);
public static void print(double);
public static void print(float);
public static void print(int);
public static void print(long);
public static void print(short);
public static void print(byte);
public static transient void printf(String, Object[]);
public static transient void printf(java.util.Locale, String, Object[]);
public static void main(String[]);
static void ();
}

StdRandom.class
public final synchronized class StdRandom {
private static java.util.Random random;
private static long seed;
private void StdRandom();
public static void setSeed(long);
public static long getSeed();
public static double uniform();
public static int uniform(int);
public static long uniform(long);
public static double random();
public static int uniform(int, int);
public static double uniform(double, double);
public static boolean bernoulli(double);
public static boolean bernoulli();
public static double gaussian();
public static double gaussian(double, double);
public static int geometric(double);
public static int poisson(double);
public static double pareto();
public static double pareto(double);
public static double cauchy();
public static int discrete(double[]);
public static int discrete(int[]);
public static double exp(double);
public static void shuffle(Object[]);
public static void shuffle(double[]);
public static void shuffle(int[]);
public static void shuffle(char[]);
public static void shuffle(Object[], int, int);
public static void shuffle(double[], int, int);
public static void shuffle(int[], int, int);
public static int[] permutation(int);
public static int[] permutation(int, int);
private static void validateNotNull(Object);
private static void validateSubarrayIndices(int, int, int);
public static void main(String[]);
static void ();
}

StdStats.class
public final synchronized class StdStats {
private void StdStats();
public static double max(double[]);
public static double max(double[], int, int);
public static int max(int[]);
public static double min(double[]);
public static double min(double[], int, int);
public static int min(int[]);
public static double mean(double[]);
public static double mean(double[], int, int);
public static double mean(int[]);
public static double var(double[]);
public static double var(double[], int, int);
public static double var(int[]);
public static double varp(double[]);
public static double varp(double[], int, int);
public static double stddev(double[]);
public static double stddev(int[]);
public static double stddev(double[], int, int);
public static double stddevp(double[]);
public static double stddevp(double[], int, int);
private static double sum(double[]);
private static double sum(double[], int, int);
private static int sum(int[]);
public static void plotPoints(double[]);
public static void plotLines(double[]);
public static void plotBars(double[]);
private static void validateNotNull(Object);
private static void validateSubarrayIndices(int, int, int);
public static void main(String[]);
}

Stopwatch.class
public synchronized class Stopwatch {
private final long start;
public void Stopwatch();
public double elapsedTime();
public static void main(String[]);
}

StopwatchCPU.class
public synchronized class StopwatchCPU {
private static final double NANOSECONDS_PER_SECOND = 1.0E9;
private final management.ThreadMXBean threadTimer;
private final long start;
public void StopwatchCPU();
public double elapsedTime();
}

TestIntroCS.class
public synchronized class TestIntroCS {
public void TestIntroCS();
public static void main(String[]);
}

UnicodeTest.class
public synchronized class UnicodeTest {
private static final int CHARS_PER_LINE = 16;
private static final int MAX_CHAR = 65536;
private void UnicodeTest();
private static String toString(int);
public static void main(String[]);
}

InTest.txt
This is a test file.
Here is line 2.

mandrill

What Will You Get?

We provide professional writing services to help you score straight A’s by submitting custom written assignments that mirror your guidelines.

Premium Quality

Get result-oriented writing and never worry about grades anymore. We follow the highest quality standards to make sure that you get perfect assignments.

Experienced Writers

Our writers have experience in dealing with papers of every educational level. You can surely rely on the expertise of our qualified professionals.

On-Time Delivery

Your deadline is our threshold for success and we take it very seriously. We make sure you receive your papers before your predefined time.

24/7 Customer Support

Someone from our customer support team is always here to respond to your questions. So, hit us up if you have got any ambiguity or concern.

Complete Confidentiality

Sit back and relax while we help you out with writing your papers. We have an ultimate policy for keeping your personal and order-related details a secret.

Authentic Sources

We assure you that your document will be thoroughly checked for plagiarism and grammatical errors as we use highly authentic and licit sources.

Moneyback Guarantee

Still reluctant about placing an order? Our 100% Moneyback Guarantee backs you up on rare occasions where you aren’t satisfied with the writing.

Order Tracking

You don’t have to wait for an update for hours; you can track the progress of your order any time you want. We share the status after each step.

image

Areas of Expertise

Although you can leverage our expertise for any writing task, we have a knack for creating flawless papers for the following document types.

Areas of Expertise

Although you can leverage our expertise for any writing task, we have a knack for creating flawless papers for the following document types.

image

Trusted Partner of 9650+ Students for Writing

From brainstorming your paper's outline to perfecting its grammar, we perform every step carefully to make your paper worthy of A grade.

Preferred Writer

Hire your preferred writer anytime. Simply specify if you want your preferred expert to write your paper and we’ll make that happen.

Grammar Check Report

Get an elaborate and authentic grammar check report with your work to have the grammar goodness sealed in your document.

One Page Summary

You can purchase this feature if you want our writers to sum up your paper in the form of a concise and well-articulated summary.

Plagiarism Report

You don’t have to worry about plagiarism anymore. Get a plagiarism report to certify the uniqueness of your work.

Free Features $66FREE

  • Most Qualified Writer $10FREE
  • Plagiarism Scan Report $10FREE
  • Unlimited Revisions $08FREE
  • Paper Formatting $05FREE
  • Cover Page $05FREE
  • Referencing & Bibliography $10FREE
  • Dedicated User Area $08FREE
  • 24/7 Order Tracking $05FREE
  • Periodic Email Alerts $05FREE
image

Our Services

Join us for the best experience while seeking writing assistance in your college life. A good grade is all you need to boost up your academic excellence and we are all about it.

  • On-time Delivery
  • 24/7 Order Tracking
  • Access to Authentic Sources
Academic Writing

We create perfect papers according to the guidelines.

Professional Editing

We seamlessly edit out errors from your papers.

Thorough Proofreading

We thoroughly read your final draft to identify errors.

image

Delegate Your Challenging Writing Tasks to Experienced Professionals

Work with ultimate peace of mind because we ensure that your academic work is our responsibility and your grades are a top concern for us!

Check Out Our Sample Work

Dedication. Quality. Commitment. Punctuality

Categories
All samples
Essay (any type)
Essay (any type)
The Value of a Nursing Degree
Undergrad. (yrs 3-4)
Nursing
2
View this sample

It May Not Be Much, but It’s Honest Work!

Here is what we have achieved so far. These numbers are evidence that we go the extra mile to make your college journey successful.

0+

Happy Clients

0+

Words Written This Week

0+

Ongoing Orders

0%

Customer Satisfaction Rate
image

Process as Fine as Brewed Coffee

We have the most intuitive and minimalistic process so that you can easily place an order. Just follow a few steps to unlock success.

See How We Helped 9000+ Students Achieve Success

image

We Analyze Your Problem and Offer Customized Writing

We understand your guidelines first before delivering any writing service. You can discuss your writing needs and we will have them evaluated by our dedicated team.

  • Clear elicitation of your requirements.
  • Customized writing as per your needs.

We Mirror Your Guidelines to Deliver Quality Services

We write your papers in a standardized way. We complete your work in such a way that it turns out to be a perfect description of your guidelines.

  • Proactive analysis of your writing.
  • Active communication to understand requirements.
image
image

We Handle Your Writing Tasks to Ensure Excellent Grades

We promise you excellent grades and academic excellence that you always longed for. Our writers stay in touch with you via email.

  • Thorough research and analysis for every order.
  • Deliverance of reliable writing service to improve your grades.
Place an Order Start Chat Now
image

Order your essay today and save 30% with the discount code Happy