commit bdf71aef375b6957f0a66b722d6217a5d526e3d7 Author: Xi Xu Date: Sun Mar 17 22:30:49 2024 +0800 Initial commit diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..638b9b9 --- /dev/null +++ b/.clang-format @@ -0,0 +1,39 @@ +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AllowShortBlocksOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +BasedOnStyle: LLVM +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true +BreakBeforeBraces: Custom +ColumnLimit: 0 +Cpp11BracedListStyle: false +FixNamespaceComments: false +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: All +PointerAlignment: Right +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4a68d18 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "windowsSdkVersion": "10.0.22621.0", + "compilerPath": "D:/msys64/ucrt64/bin/g++.exe", + "cStandard": "gnu23", + "cppStandard": "gnu++23", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..754bc83 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + "configurations": [ + { + "name": "C/C++: g++.exe build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", + "args": [], + "stopAtEntry": false, + "cwd": "D:/msys64/ucrt64/bin", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "D:\\msys64\\ucrt64\\bin\\gdb.exe", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: g++.exe build active file", + "internalConsoleOptions": "neverOpen" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a7f96cd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "files.defaultLanguage": "cpp" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..17dc7c5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,26 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: g++.exe build active file", + "command": "D:/msys64/ucrt64/bin/g++.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + // "${fileDirname}\\*.cpp", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe" + ], + "options": { + "cwd": "D:/msys64/ucrt64/bin" + }, + "problemMatcher": [ + "$gcc" + ], + "group": "build", + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e62ec04 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ +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 +. diff --git a/Miscellaneous/CComplex.cpp b/Miscellaneous/CComplex.cpp new file mode 100644 index 0000000..72c4bac --- /dev/null +++ b/Miscellaneous/CComplex.cpp @@ -0,0 +1,66 @@ +#include + +using namespace std; + +class Complex { +private: + double real; + double imag; + +public: + Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} + + bool operator==(const Complex &c) const { + return real == c.real && imag == c.imag; + } + + double operator!() const { + return sqrt(real * real + imag * imag); + } + + Complex operator~() const { + return Complex(real, -imag); + } + + friend istream &operator>>(istream &input, Complex &c) { + string si; + input >> si; + stringstream i(si); + char sign; + i >> c.real >> sign >> c.imag; + if (sign == '-') + c.imag = -c.imag; + return input; + } + + friend ostream &operator<<(ostream &output, const Complex &c) { + if (c.imag > 0) + output << c.real << " + " << c.imag << "i"; + else if (c.imag < 0) + output << c.real << " - " << -c.imag << "i"; + else + output << c.real; + return output; + } +}; + +int main() { + Complex c1; + Complex c2; + cout << "c1 = "; + cin >> c1; + cout << "c2 ="; + cin >> c2; + cout << "|c1| = " << !c1 << endl; + cout << "|c2| = " << !c2 << endl; + cout << "~c1 = " << ~c1 << endl; + cout << "~c2 = " << ~c2 << endl; + if (c1 == c2) { + cout << "c1 == c2" << endl; + } + else { + cout << "c1 != c2" << endl; + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/CRational.cpp b/Miscellaneous/CRational.cpp new file mode 100644 index 0000000..6103f39 --- /dev/null +++ b/Miscellaneous/CRational.cpp @@ -0,0 +1,146 @@ +#include + +using namespace std; + +// int gcd(int m, int n) +// { +// while (n != 0) +// { +// int t = m % n; +// m = n; +// n = t; +// } +// return m; +// } + +class Rational { +private: + int numerator; + int denominator; + +public: + Rational(int num, int den); + friend ostream &operator<<(ostream &output, const Rational &r); + Rational operator+(const Rational &r) const; + Rational operator-(const Rational &r) const; + Rational operator*(const Rational &r) const; + Rational operator/(const Rational &r) const; + bool operator==(const Rational &r) const; + bool operator>(const Rational &r) const; + Rational operator~() const; + Rational operator!() const; +}; + +Rational::Rational(int num, int den) { + numerator = num; + denominator = den; + if (numerator == 0 && denominator == 0) + ; + else if (numerator == 0) + denominator = 1; + else if (denominator == 0) + numerator = 1; + else { + int _gcd = gcd(numerator, denominator); + numerator /= _gcd; + denominator /= _gcd; + if (denominator < 0) { + numerator *= -1; + denominator *= -1; + } + } +} + +ostream &operator<<(ostream &output, const Rational &r) { + if (r.numerator == 0 && r.denominator == 0) + output << "NaN"; + else if (r.denominator == 0) + output << "Inf"; + else + output << r.numerator << " / " << r.denominator; + return output; +} + +Rational Rational::operator+(const Rational &r) const { + int num, den; + if (numerator != 0 && r.numerator != 0 && denominator == 0 && r.denominator == 0) { + num = 1; + den = 0; + } + else { + num = numerator * r.denominator + r.numerator * denominator; + den = denominator * r.denominator; + } + return Rational(num, den); +} + +Rational Rational::operator-(const Rational &r) const { + int num = numerator * r.denominator - r.numerator * denominator; + int den = denominator * r.denominator; + return Rational(num, den); +} + +Rational Rational::operator*(const Rational &r) const { + int num = numerator * r.numerator; + int den = denominator * r.denominator; + return Rational(num, den); +} + +Rational Rational::operator/(const Rational &r) const { + int num, den; + if (denominator == 0 && r.denominator == 0) { + num = 0; + den = 0; + } + else { + num = numerator * r.denominator; + den = r.numerator * denominator; + } + return Rational(num, den); +} + +bool Rational::operator==(const Rational &r) const { + return numerator == r.numerator && denominator == r.denominator; +} + +bool Rational::operator>(const Rational &r) const { + return 1.0 * numerator / denominator > 1.0 * r.numerator / r.denominator; +} + +Rational Rational::operator~() const { + return Rational(-numerator, denominator); +} + +Rational Rational::operator!() const { + int num = denominator, den = numerator; + if (den < 0) { + num *= -1; + den *= -1; + } + return Rational(num, den); +} + +int main() { + char c; + int num1, den1, num2, den2; + cout << "r1 = "; + cin >> num1 >> c >> den1; + cout << "r2 = "; + cin >> num2 >> c >> den2; + Rational r1(num1, den1), r2(num2, den2); + cout << "r1 + r2 = " << r1 + r2 << endl + << "r1 - r2 = " << r1 - r2 << endl + << "r1 * r2 = " << r1 * r2 << endl + << "r1 / r2 = " << r1 / r2 << endl + << "~r1 = " << ~r1 << ", " + << "~r2 = " << ~r2 << endl + << "!r1 = " << !r1 << ", " + << "!r2 = " << !r2 << endl; + if (r1 == r2) + cout << "r1 == r2" << endl; + else if (r1 > r2) + cout << "r1 > r2" << endl; + else + cout << "r1 < r2" << endl; + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/CSString.cpp b/Miscellaneous/CSString.cpp new file mode 100644 index 0000000..418b02d --- /dev/null +++ b/Miscellaneous/CSString.cpp @@ -0,0 +1,195 @@ +// 模仿c++ 自带string类,设计一个字符串类SString,要求至少有以下功能: +// (1)字符串初始化 +// (2)字符串类对象能相互赋值(重载运算符 =) +// (3)获得字符串长度 +// (4)字符串连接,通过重载运算符 + 实现 +// (5)字符串显示功能 +// (6)字符串插入功能 +// (7)字符串删除功能 +// (8)取子串功能 +// (9)字符串查找功能 +// (10)字符串比较功能,重载运算符 == + +#include + +using namespace std; + +const int N = 1e6 + 2; + +class SString { +private: + char *p; + int len; + +public: + SString(); + SString(const char *s); + SString(const SString &s); + + ~SString(); + + SString &operator=(const char *s); + SString &operator=(const SString &s); + + SString operator+(const char *s) const; + SString operator+(const SString &s) const; + + bool operator==(const char *s) const; + bool operator==(const SString &s) const; + + int length() const; + + void insert(int pos, const char *s); + void insert(int pos, const SString &s); + + void erase(int pos, int n); + + SString substr(int pos, int n) const; + + int find(const char *s) const; + int find(const SString &s) const; + + friend ostream &operator<<(ostream &out, const SString &s); + friend istream &operator>>(istream &in, SString &s); +}; + +ostream &operator<<(ostream &out, const SString &s); + +SString::SString() { + p = nullptr; + len = 0; +} + +SString::SString(const char *s) { + len = strlen(s); + p = new char[len + 1]; + strcpy(p, s); +} + +SString::SString(const SString &s) { + len = s.len; + p = new char[len + 1]; + strcpy(p, s.p); +} + +SString::~SString() { + delete[] p; +} + +SString &SString::operator=(const char *s) { + if (p != s) { + delete[] p; + len = strlen(s); + p = new char[len + 1]; + strcpy(p, s); + } + return *this; +} + +SString &SString::operator=(const SString &s) { + if (this != &s) { + delete[] p; + len = s.len; + p = new char[len + 1]; + strcpy(p, s.p); + } + return *this; +} + +SString SString::operator+(const char *s) const { + SString temp; + temp.len = len + strlen(s); + temp.p = new char[temp.len + 1]; + strcpy(temp.p, p); + strcat(temp.p, s); + return temp; +} + +SString SString::operator+(const SString &s) const { + return *this + s.p; +} + +bool SString::operator==(const char *s) const { + return strcmp(p, s) == 0; +} + +bool SString::operator==(const SString &s) const { + return *this == s.p; +} + +int SString::length() const { + return len; +} + +void SString::insert(int pos, const char *s) { + if (pos < 0 || pos > len) { + cerr << "Invalid position" << endl; + return; + } + int slen = strlen(s); + char *temp = new char[len + slen + 1]; + strncpy(temp, p, pos); + strcpy(temp + pos, s); + strcpy(temp + pos + slen, p + pos); + delete[] p; + p = temp; + len += slen; +} + +void SString::insert(int pos, const SString &s) { + insert(pos, s.p); +} + +void SString::erase(int pos, int n) { + if (pos < 0 || pos >= len || n < 0 || n > len - pos) { + cerr << "Invalid arguments" << endl; + return; + } + char *temp = new char[len - n + 1]; + strncpy(temp, p, pos); + strcpy(temp + pos, p + pos + n); + delete[] p; + p = temp; + len -= n; +} + +SString SString::substr(int pos, int n) const { + if (pos < 0 || pos >= len || n < 0 || n > len - pos) { + cerr << "Invalid arguments" << endl; + return SString(); + } + char *temp = new char[n + 1]; + strncpy(temp, p + pos, n); + temp[n] = '\0'; + SString result(temp); + delete[] temp; + return result; +} + +int SString::find(const char *s) const { + char *pos = strstr(p, s); + if (pos == nullptr) { + return -1; + } + else { + return pos - p; + } +} + +int SString::find(const SString &s) const { + return find(s.p); +} + +ostream &operator<<(ostream &out, const SString &s) { + out << s.p; + return out; +} + +istream &operator>>(istream &in, SString &s) { + char t[N]; + in >> t; + s.len = strlen(t); + s.p = new char[s.len + 1]; + strcpy(s.p, t); + return in; +} \ No newline at end of file diff --git a/Miscellaneous/FILELINEDATETIME.cpp b/Miscellaneous/FILELINEDATETIME.cpp new file mode 100644 index 0000000..5f6f30e --- /dev/null +++ b/Miscellaneous/FILELINEDATETIME.cpp @@ -0,0 +1,9 @@ +#include + +using namespace std; + +int main(int argc, char **argv) { + printf("%s: %d\n", __FILE__, __LINE__); + printf("%s, %s\n", __DATE__, __TIME__); + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/Joseph_ring.cpp b/Miscellaneous/Joseph_ring.cpp new file mode 100644 index 0000000..0924580 --- /dev/null +++ b/Miscellaneous/Joseph_ring.cpp @@ -0,0 +1,43 @@ +#include + +using namespace std; + +int main(int argc, char **argv) { + int n, m; + + scanf("%d %d", &n, &m); + + int out[n]; + + for (int i = 0; i < n; i++) { + out[i] = 0; + } + + int i = 0, cnt = 0, r = 1; + + while (r < n) { + if (!out[i]) { + cnt++; + } + + if (cnt == m) { + cnt = 0; + out[i] = 1; + r++; + } + + i++; + + if (i > n - 1) { + i = i % n; + } + } + + for (int i = 0; i < n; i++) { + if (!out[i]) { + printf("%d\n", i + 1); + } + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/O2.cpp b/Miscellaneous/O2.cpp new file mode 100644 index 0000000..7857f44 --- /dev/null +++ b/Miscellaneous/O2.cpp @@ -0,0 +1,3 @@ +#pragma GCC optimize(1) +#pragma GCC optimize(2) +#pragma GCC optimize(3, "Ofast", "inline") \ No newline at end of file diff --git a/Miscellaneous/array_union.cpp b/Miscellaneous/array_union.cpp new file mode 100644 index 0000000..495e4d6 --- /dev/null +++ b/Miscellaneous/array_union.cpp @@ -0,0 +1,64 @@ +#include + +using namespace std; + +void bubble_sort(int arr[], int len); + +int main(int argc, char const *argv[]) { + int m; + scanf("%d", &m); + int *a = (int *)malloc(m * sizeof(int)); + for (int i = 0; i < m; i++) { + scanf("%d", &a[i]); + } + + int n; + scanf("%d", &n); + int *b = (int *)malloc(n * sizeof(int)); + for (int i = 0; i < n; i++) { + scanf("%d", &b[i]); + } + + int c[40]; + int t = 0, cnt; + + for (int i = 0; i < m; i++) { + c[i] = a[i]; + } + + for (int j = 0; j < n; j++) { + cnt = 0; + for (int i = 0; i < m; i++) { + if (b[j] != a[i]) { + cnt++; + } + if (cnt == m) { + c[m + (t++)] = b[j]; + } + } + } + + free(a); + free(b); + + bubble_sort(c, m + t); + + for (int i = 0; i < m + t; i++) { + printf("%d ", c[i]); + } + + return 0; +} + +void bubble_sort(int arr[], int len) { + int temp; + for (int i = 0; i < len - 1; i++) { + for (int j = 0; j < len - 1 - i; j++) { + if (arr[j] < arr[j + 1]) { + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +} diff --git a/Miscellaneous/average_2.cpp b/Miscellaneous/average_2.cpp new file mode 100644 index 0000000..cd40b3c --- /dev/null +++ b/Miscellaneous/average_2.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +int main() { + int sum = 0; + int count = 0; + int number = 0; + + scanf("%d", &number); + + while (number != -1) { + sum += number; + count++; + scanf("%d", &number); + } + + double dsum = sum; + + printf("%f\n", dsum / count); + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/bubble_sort.cpp b/Miscellaneous/bubble_sort.cpp new file mode 100644 index 0000000..3b6b768 --- /dev/null +++ b/Miscellaneous/bubble_sort.cpp @@ -0,0 +1,44 @@ +#include + +using namespace std; + +#define N 1000 + +void bubble_sort(int arr[], int len) { + int temp; + for (int i = 0; i < len - 1; i++) { + for (int j = 0; j < len - 1 - i; j++) { + if (arr[j] > arr[j + 1]) { + temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } +} + +int main(void) { + int arr[N] = { 0 }; + int cnt = 0; + + for (int i = 0; i < N; i++) { + scanf("%d", &arr[i]); + + if (arr[i] == -1) { + break; + } + cnt++; + } + + bubble_sort(arr, cnt); + + for (int i = 0; i < cnt; i++) { + if (arr[i] != 0 && arr[i] != -1) { + printf("%d ", arr[i]); + } + } + + printf("\n"); + + return 0; +} diff --git a/Miscellaneous/calculator.cpp b/Miscellaneous/calculator.cpp new file mode 100644 index 0000000..b1f9df8 --- /dev/null +++ b/Miscellaneous/calculator.cpp @@ -0,0 +1,77 @@ +#include + +using namespace std; + +string s; + +int change(int l, int r) { + + int sum = 0; + + for (int i = l; i <= r; i++) + sum = sum * 10 + s[i] - '0'; + + return sum; +} + +int calc(int l, int r) { + + int cnt = 0, pos1 = -1, pos2 = -1, pos3 = -1; + + for (int i = l; i <= r; i++) { + + if (s[i] == '(') + cnt++; + if (s[i] == ')') + cnt--; + + if (cnt <= 0 && (s[i] == '+' || s[i] == '-')) + pos1 = i; + if (cnt <= 0 && (s[i] == '*' || s[i] == '/')) + pos2 = i; + if (cnt <= 0 && s[i] == '^') + pos3 = i; + } + + if (pos1 == -1 && pos2 == -1 && pos3 == -1 && cnt == 0) { + + if (s[l] == '(') + return calc(l + 1, r - 1); + else + return change(l, r); + } + + if (pos1 != -1) { + + if (s[pos1] == '+') + return calc(l, pos1 - 1) + calc(pos1 + 1, r); + else + return calc(l, pos1 - 1) - calc(pos1 + 1, r); + } + + if (pos2 != -1) { + + if (s[pos2] == '*') + return calc(l, pos2 - 1) * calc(pos2 + 1, r); + else + return calc(l, pos2 - 1) / calc(pos2 + 1, r); + } + + if (pos3 != -1) + return pow(calc(l, pos3 - 1), calc(pos3 + 1, r)); + + if (cnt > 0 && s[l] == '(') + return calc(l + 1, r); + + if (cnt < 0 && s[l] == ')') + return calc(l, r - 1); + return 0; +} + +int main() { + cin >> s; + + cout << calc(0, s.length() - 1); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/climb.cpp b/Miscellaneous/climb.cpp new file mode 100644 index 0000000..6c21e40 --- /dev/null +++ b/Miscellaneous/climb.cpp @@ -0,0 +1,24 @@ +#include +#include + +using namespace std; + +int main(void) { + int n, n1 = 0, n2 = 1, ret = 2; + + scanf("%d", &n); + + if (n < 3) { + printf("%d\n", n); + } + else { + for (int i = 2; i < n; i++) { + n1 = n2; + n2 = ret; + ret = n1 + n2; + } + printf("%d\n", ret); + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/coin_goto.cpp b/Miscellaneous/coin_goto.cpp new file mode 100644 index 0000000..bed964e --- /dev/null +++ b/Miscellaneous/coin_goto.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +int main(void) { + int x; + printf("һǸ"); + scanf("%d", &x); + + int o, f, t, tt, ft, h; + + for (o = 0; o <= x; o++) { + for (f = 0; f <= x / 5; f++) { + for (t = 0; t <= x / 10; t++) { + for (tt = 0; tt <= x / 20; tt++) { + for (ft = 0; ft <= x / 50; ft++) { + for (h = 0; h <= x / 100; h++) { + if (o * 1 + f * 5 + t * 10 + tt * 20 + ft * 50 + h * 100 == x) { + printf("Խ %d һԪ%d Ԫ%d ʮԪ%d ŶʮԪ%d ʮԪ %d һԪõ %d Ԫ\n", o, f, t, tt, ft, h, x); + goto out; + } + } + } + } + } + } + } +out: + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/coin_relay.cpp b/Miscellaneous/coin_relay.cpp new file mode 100644 index 0000000..91ffb33 --- /dev/null +++ b/Miscellaneous/coin_relay.cpp @@ -0,0 +1,42 @@ +#include + +using namespace std; + +int main(void) { + int x; + int o, f, t, tt, ft, h; + int exit = 0; + + printf("һǸ"); + scanf("%d", &x); + + for (o = 0; o <= x; o++) { + for (f = 0; f <= x / 5; f++) { + for (t = 0; t <= x / 10; t++) { + for (tt = 0; tt <= x / 20; tt++) { + for (ft = 0; ft <= x / 50; ft++) { + for (h = 0; h <= x / 100; h++) { + if (o * 1 + f * 5 + t * 10 + tt * 20 + ft * 50 + h * 100 == x) { + printf("Խ %d һԪ%d Ԫ%d ʮԪ%d ŶʮԪ%d ʮԪ %d һԪõ %d Ԫ\n", o, f, t, tt, ft, h, x); + exit = 1; + break; + } + } + if (exit) + break; + } + if (exit) + break; + } + if (exit) + break; + } + if (exit) + break; + } + if (exit) + break; + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/date_difference.cpp b/Miscellaneous/date_difference.cpp new file mode 100644 index 0000000..6a00f78 --- /dev/null +++ b/Miscellaneous/date_difference.cpp @@ -0,0 +1,49 @@ +#include + +using namespace std; + +struct Date { + int year; + int month; + int day; +} d1, d2; + +int m[2][13] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +int count(struct Date *p_d); + +int main(int argc, char *argv[]) { + int ans = 0; + + scanf("%d %d %d", &d1.year, &d1.month, &d1.day); + scanf("%d %d %d", &d2.year, &d2.month, &d2.day); + + for (int i = d1.year; i < d2.year; i++) { + if ((i % 100 != 0 && i % 4 == 0) || i % 400 == 0) + ans += 366; + else + ans += 365; + } + + ans += count(&d2) - count(&d1); + + printf("%d\n", ans); + + return 0; +} + +int count(struct Date *p_d) { + int n = 0; + + if ((p_d->year % 100 != 0 && p_d->year % 4 == 0) || p_d->year % 400 == 0) + for (int i = 1; i < p_d->month; i++) + n += m[1][i]; + else + for (int i = 1; i < p_d->month; i++) + n += m[0][i]; + + return n + p_d->day; +} \ No newline at end of file diff --git a/Miscellaneous/decimal_to_fraction.cpp b/Miscellaneous/decimal_to_fraction.cpp new file mode 100644 index 0000000..9ec93b3 --- /dev/null +++ b/Miscellaneous/decimal_to_fraction.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +int main() { + double decimal; + double temp; + int integer, numerator, denominator; + int d = -1; + int g; + + cin >> decimal; + + integer = (int)decimal; + temp = decimal - integer; + + while ((int)temp % 10 != 0 || (int)temp == 0) { + temp *= 10; + d++; + } + + temp /= 10; + + g = (int)gcd((int)temp, (int)pow(10, d)); + + numerator = (int)(temp / g); + denominator = (int)(pow(10, d) / g); + + cout << integer << numerator << denominator << endl; + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/digit.cpp b/Miscellaneous/digit.cpp new file mode 100644 index 0000000..d504f1f --- /dev/null +++ b/Miscellaneous/digit.cpp @@ -0,0 +1,21 @@ +#include + +using namespace std; + +int main() { + printf("һ"); + + int x = 0; + scanf("%d", &x); + + int n = 0; + + do { + n++; + x /= 10; + } while (x > 0); + + printf("һ %d λ\n", n); + + return 0; +} diff --git a/Miscellaneous/fabonacci.cpp b/Miscellaneous/fabonacci.cpp new file mode 100644 index 0000000..a117fc2 --- /dev/null +++ b/Miscellaneous/fabonacci.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +int fabonacci(int n); + +int main(void) { + int n; + + scanf("%d", &n); + + printf("%d\n", fabonacci(n)); + + return 0; +} + +int fabonacci(int n) { + int ret; + + if (n == 0 || n == 1) { + ret = n; + } + else { + ret = fabonacci(n - 1) + fabonacci(n - 2); + } + + return ret; +} \ No newline at end of file diff --git a/Miscellaneous/factorial.cpp b/Miscellaneous/factorial.cpp new file mode 100644 index 0000000..053b35e --- /dev/null +++ b/Miscellaneous/factorial.cpp @@ -0,0 +1,17 @@ +#include + +using namespace std; + +int main() { + int ret = 1; + int n; + scanf("%d", &n); + + for (; n > 1; n--) { + ret *= n; + } + + printf("%d\n", ret); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/func.cpp b/Miscellaneous/func.cpp new file mode 100644 index 0000000..ef3fb20 --- /dev/null +++ b/Miscellaneous/func.cpp @@ -0,0 +1,25 @@ +#include + +using namespace std; + +int main() { + printf("x="); + + double x, y; + + scanf("%lf", &x); + + if (x > 0) { + y = 2 * x; + } + else if (x == 0) { + y = 0; + } + else { + y = -1; + } + + printf("f(x)=%f\n", y); + + return 0; +} diff --git a/Miscellaneous/func_2.cpp b/Miscellaneous/func_2.cpp new file mode 100644 index 0000000..a891f61 --- /dev/null +++ b/Miscellaneous/func_2.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +int main() { + printf("x="); + + double x, y; + int type; + + scanf("%lf", &x); + + type = x < 0; + + switch (type) { + case 1: + y = -1; + break; + + case 0: + y = 2 * x; + break; + } + + printf("f(x)=%f\n", y); + + return 0; +} diff --git a/Miscellaneous/gcd.cpp b/Miscellaneous/gcd.cpp new file mode 100644 index 0000000..5470e53 --- /dev/null +++ b/Miscellaneous/gcd.cpp @@ -0,0 +1,18 @@ +#include + +using namespace std; + +int main(void) { + int a, b; + int t; + scanf("%d %d", &a, &b); + + while (b != 0) { + t = a % b; + a = b; + b = t; + } + printf("%d\n", a); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/grade.cpp b/Miscellaneous/grade.cpp new file mode 100644 index 0000000..d5d8361 --- /dev/null +++ b/Miscellaneous/grade.cpp @@ -0,0 +1,35 @@ +#include + +using namespace std; + +int main() { + int grade = 0; + + scanf("%d", &grade); + + grade /= 10; + + switch (grade) { + case 10: + case 9: + printf("A\n"); + break; + + case 8: + printf("B\n"); + break; + + case 7: + printf("C\n"); + break; + + case 6: + printf("D\n"); + break; + + default: + printf("F\n"); + } + + return 0; +} diff --git a/Miscellaneous/hanoi.cpp b/Miscellaneous/hanoi.cpp new file mode 100644 index 0000000..1114c23 --- /dev/null +++ b/Miscellaneous/hanoi.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +void hanoi(int n, char a, char b, char c); + +int main(int argc, char const *argv[]) { + int n; + + printf("input the number of disk: "); + + scanf("%d", &n); + + printf("the steps for %d disk are:\n", n); + + hanoi(n, 'A', 'B', 'C'); + + return 0; +} + +// 搬动 n 个盘, 从 a 到 b,c 为中间过渡 +void hanoi(int n, char a, char b, char c) { + if (n == 1) { + printf("%c-->%c\n", a, b); + } + else { + hanoi(n - 1, a, c, b); + printf("%c-->%c\n", a, c); + hanoi(n - 1, c, b, a); + } +} \ No newline at end of file diff --git a/Miscellaneous/integer_factorization.cpp b/Miscellaneous/integer_factorization.cpp new file mode 100644 index 0000000..6ab130d --- /dev/null +++ b/Miscellaneous/integer_factorization.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +int main(void) { + int x, mask = 1; + scanf("%d", &x); + + int t = x; + + while (t > 9) { + t /= 10; + mask *= 10; + } + + do { + int d = x / mask; + printf("%d", d); + if (mask > 9) + ; + { + printf(" "); + } + x %= mask; + mask /= 10; + } while (mask > 0); + + return 0; +} diff --git a/Miscellaneous/integer_set.cpp b/Miscellaneous/integer_set.cpp new file mode 100644 index 0000000..ce1a526 --- /dev/null +++ b/Miscellaneous/integer_set.cpp @@ -0,0 +1,41 @@ +#include + +using namespace std; + +int main(void) { + int a; + int i, j, k; + int cnt = 0; + + scanf("%d", &a); + + i = a; + while (i <= a + 3) { + j = a; + while (j <= a + 3) { + k = a; + while (k <= a + 3) { + if (i != j) { + if (i != k) { + if (j != k) { + printf("%d%d%d", i, j, k); + cnt++; + if (cnt == 6) { + printf("\n"); + cnt = 0; + } + else { + printf(" "); + } + } + } + } + k++; + } + j++; + } + i++; + } + + return 0; +} diff --git a/Miscellaneous/linked_list.cpp b/Miscellaneous/linked_list.cpp new file mode 100644 index 0000000..a063b92 --- /dev/null +++ b/Miscellaneous/linked_list.cpp @@ -0,0 +1,73 @@ +#include +#include + +typedef struct _node { + int value; + struct _node *next; +} Node; + +typedef struct _list { + Node *head; +} List; + +Node *creat_node(int value) { + Node *new_node = (Node *)malloc(sizeof(Node)); + new_node->value = value; + new_node->next = NULL; + return new_node; +} + +void head_insert(List *list, int value) { + Node *new_node = creat_node(value); + new_node->next = list->head; + list->head = new_node; +} + +void tail_insert(List *list, int value) { + Node *new_node = creat_node(value); + if (!list->head) { + list->head = new_node; + } + else { + Node *current = list->head; + for (; current->next; current = current->next) + ; + current->next = new_node; + } +} + +Node *search_node(List *list, int value) { + Node *current = list->head; + for (; current != NULL && current->value != value; current = current->next) + ; + return current; +} + +void delete_node(List *list, int value) { + for (Node *current = list->head, *prev = NULL; current; prev = current, current = current->next) { + if (current->value == value) { + if (prev) { + prev->next = current->next; + } + else { + list->head = current->next; + } + free(current); + break; + } + } +} + +void print_list(List *list) { + for (Node *current = list->head; current; current = current->next) { + printf("%d ", current->value); + } + printf("\n"); +} + +void clear_list(List *list) { + for (Node *current = list->head, *subs; current; current = subs) { + subs = current->next; + free(current); + } +} \ No newline at end of file diff --git a/Miscellaneous/loop.cpp b/Miscellaneous/loop.cpp new file mode 100644 index 0000000..e3f64b2 --- /dev/null +++ b/Miscellaneous/loop.cpp @@ -0,0 +1,36 @@ +#include + +using namespace std; + +int loop(int x) { + int y = x; + int digit = 0; + int z = 0; + int ret = 0; + + while (x > 0) { + digit = x % 10; + z = z * 10 + digit; + x /= 10; + } + + if (y == z) { + ret = 1; + } + + return ret; +} + +int main(void) { + int a, b; + + scanf("%d %d", &a, &b); + + for (int i = a; i <= b; i++) { + if (loop(i) && i % 2 == 0) { + printf("%d\n", i); + } + } + + return 0; +} diff --git a/Miscellaneous/matrix_multiplication.cpp b/Miscellaneous/matrix_multiplication.cpp new file mode 100644 index 0000000..7fc297d --- /dev/null +++ b/Miscellaneous/matrix_multiplication.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +int main(int argc, char const *argv[]) { + int n; + + scanf("%d", &n); + + int *a = (int *)malloc(n * sizeof(int)); + + for (int i = 0; i < n; i++) { + scanf("%d", &a[i]); + } + + int temp; + + for (int i = 0; i < n / 2; i++) { + temp = a[i]; + a[i] = a[n - i - 1]; + a[n - i - 1] = temp; + } + + for (int i = 0; i < n; i++) { + printf("%d ", a[i]); + } + + free(a); + + return 0; +} diff --git a/Miscellaneous/matrix_transposition.cpp b/Miscellaneous/matrix_transposition.cpp new file mode 100644 index 0000000..12f5968 --- /dev/null +++ b/Miscellaneous/matrix_transposition.cpp @@ -0,0 +1,25 @@ +#include + +using namespace std; + +int main() { + int h, w; + + scanf("%d %d", &h, &w); + + int a[h][w], b[w][h]; + + for (int i = 0; i < h; i++) { + for (int j = 0; j < w; j++) { + scanf("%d", &a[i][j]); + } + } + + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + b[i][j] = a[j][i]; + } + } + + return 0; +} diff --git a/Miscellaneous/merge_strings.cpp b/Miscellaneous/merge_strings.cpp new file mode 100644 index 0000000..ce85c83 --- /dev/null +++ b/Miscellaneous/merge_strings.cpp @@ -0,0 +1,48 @@ +// 编写一个函数void str_bin(char str1[], char str2[]), str1、str2是两个有序字符串(其中字符按ASCII码从小到大排序),将str2合并到字符串str1中,要求合并后的字符串仍是有序的,允许字符重复。在main函数中测试该函数:从键盘输入两个有序字符串,然后调用该函数,最后输出合并后的结果。 + +#include + +using namespace std; + +void str_bin(char str1[], char str2[]); + +int main(int argc, char **argv) { + char a[101], b[101]; + + scanf("%s", a); + scanf("%s", b); + + str_bin(a, b); + + puts(a); + + return 0; +} + +void str_bin(char str1[], char str2[]) { + char temp[202]; + int i = 0, j = 0, k = 0; + while (str1[i] != '\0' && str2[j] != '\0') { + if (str1[i] < str2[j]) { + temp[k++] = str1[i++]; + } + else if (str1[i] > str2[j]) { + temp[k++] = str2[j++]; + } + else { + temp[k++] = str1[i++]; + temp[k++] = str2[j++]; + } + } + + temp[k] = '\0'; + + if (str1[i] != '\0') { + strcat(temp, str1 + i); + } + else if (str2[j] != '\0') { + strcat(temp, str2 + j); + } + + strcpy(str1, temp); +} diff --git a/Miscellaneous/multiplication_table.cpp b/Miscellaneous/multiplication_table.cpp new file mode 100644 index 0000000..ad30cd9 --- /dev/null +++ b/Miscellaneous/multiplication_table.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +int main(void) { + const int N = 9; + + for (int i = 1; i <= N; i++) { + for (int j = 0; j <= i; j++) { + printf("%d * %d = %d", i, j, i * j); + if (i * j < 10) { + printf(" "); + } + else { + printf(" "); + } + } + printf("\n"); + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/narcissistic_number.cpp b/Miscellaneous/narcissistic_number.cpp new file mode 100644 index 0000000..2990b10 --- /dev/null +++ b/Miscellaneous/narcissistic_number.cpp @@ -0,0 +1,51 @@ +#include + +using namespace std; + +int narcissistic(int number); +void PrintN(int m, int n); + +int main() { + int m, n; + + scanf("%d %d", &m, &n); + if (narcissistic(m)) + printf("%d is a narcissistic number\n", m); + PrintN(m, n); + if (narcissistic(n)) + printf("%d is a narcissistic number\n", n); + + return 0; +} + +#include + +int narcissistic(int number) { + int temp1 = number, temp2 = number; + int i; + + for (i = 0; temp1 != 0; i++, temp1 /= 10) + ; + + int sum = 0; + int j = i; + + while (j--) { + sum += pow(temp2 % 10, i); + temp2 /= 10; + } + + if (sum == number) { + return 1; + } + else { + return 0; + } +} + +void PrintN(int m, int n) { + for (int i = m + 1; i < n; i++) { + if (narcissistic(i)) + printf("%d\n", i); + } +} diff --git a/Miscellaneous/nowcoder_beginner_Monthly_competition_60_C.cpp b/Miscellaneous/nowcoder_beginner_Monthly_competition_60_C.cpp new file mode 100644 index 0000000..0e87ac8 --- /dev/null +++ b/Miscellaneous/nowcoder_beginner_Monthly_competition_60_C.cpp @@ -0,0 +1,32 @@ +// 你通过观察发现他房间内有 n 个可用于制成绳子的物品,第 i 个的长度为 ai。当你使用第 i 个物品制作绳子时,其右侧的 k 个物品(不含第i个物品)就无法再被用于制作绳子 。最终,小竹用选择的物品制成绳子,绳子的长度是所选择物品的长度之和。小竹想知道,他能制作的绳子长度最长为多少? + +#include + +using namespace std; + +int max(int a, int b) { + return a > b ? a : b; +} + +int main(int argc, char **argv) { + int n, k; + scanf("%d %d", &n, &k); + int *temp, *ans; + ans = (int *)malloc(sizeof(int) * (n + 1)); + temp = (int *)malloc(sizeof(int) * n); + for (int i = 0; i < n; i++) + scanf("%d", &temp[i]); + for (int i = 1; i <= n; i++) { + if (i == 1) + ans[i] = temp[i - 1]; + else if (i <= k + 1) { + ans[i] = max(ans[i - 1], temp[i - 1]); + } + else { + ans[i] = max(ans[i - 1], ans[i - k - 1] + temp[i - 1]); + } + } + + printf("%d", ans[n]); + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/pi.cpp b/Miscellaneous/pi.cpp new file mode 100644 index 0000000..1ed4b05 --- /dev/null +++ b/Miscellaneous/pi.cpp @@ -0,0 +1,26 @@ +#include + +using namespace std; + +int main(int argc, char const *argv[]) { + double eps; + double pi; + double sum = 0; + int sign = 1; + + scanf("%lf", &eps); + + for (int i = 0;; i++) { + double x = sign / (sqrt(3) * pow(3, i) * (2 * i + 1)); + sum += sign / (sqrt(3) * pow(3, i) * (2 * i + 1)); + sign = -sign; + if (1 / (sqrt(3) * pow(3, i) * (2 * i + 1)) < eps) + break; + } + + pi = 6 * sum; + + printf("pi=%f\n", pi); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/prime.cpp b/Miscellaneous/prime.cpp new file mode 100644 index 0000000..b17c667 --- /dev/null +++ b/Miscellaneous/prime.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +int main(void) { + int m, n; + int cnt = 0; + int sum = 0; + + scanf("%d %d", &m, &n); + if (m == 1) { + m = 2; + } + + for (int i = m; i <= n; i++) { + int isPrime = 1; + for (int j = 2; j < i - 1; j++) { + if (i % j == 0) { + isPrime = 0; + break; + } + } + if (isPrime) { + cnt++; + sum += i; + } + } + + printf("%d %d\n", cnt, sum); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/prime_array.cpp b/Miscellaneous/prime_array.cpp new file mode 100644 index 0000000..3975425 --- /dev/null +++ b/Miscellaneous/prime_array.cpp @@ -0,0 +1,46 @@ +#include + +using namespace std; + +#define NUMBER 1000 + +int IsPrime(int x, int KnowPrimes[], int NumberOfKnowPrimes); + +int main(void) { + int prime[NUMBER] = { 2 }; + int cnt = 1; + int x = 3; + + while (cnt < NUMBER) { + if (IsPrime(x, prime, cnt)) { + prime[cnt++] = x; + } + x++; + } + + for (int i = 0; i < NUMBER; i++) { + printf("%d", prime[i]); + + if ((i + 1) % 5) { + printf("\t"); + } + else { + printf("\n"); + } + } + + return 0; +} + +int IsPrime(int x, int KnowPrimes[], int NumberOfKnowPrimes) { + int ret = 1; + + for (int i = 0; i < NumberOfKnowPrimes; i++) { + if (x % KnowPrimes[i] == 0) { + ret = 0; + break; + } + } + + return ret; +} \ No newline at end of file diff --git a/Miscellaneous/prime_array_2.cpp b/Miscellaneous/prime_array_2.cpp new file mode 100644 index 0000000..29d7d6e --- /dev/null +++ b/Miscellaneous/prime_array_2.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +#define N 100 + +int main(void) { + int prime[N]; + + for (int i = 0; i < N; i++) { + prime[i] = 1; + } + + for (int x = 2; x < N; x++) { + if (prime[x]) { + for (int i = 2; x * i < N; i++) { + prime[x * i] = 0; + } + } + } + + for (int i = 2; i < N; i++) { + if (prime[i]) { + printf("%d ", i); + } + } + + return 0; +} diff --git a/Miscellaneous/prime_file.cpp b/Miscellaneous/prime_file.cpp new file mode 100644 index 0000000..4a619e6 --- /dev/null +++ b/Miscellaneous/prime_file.cpp @@ -0,0 +1,54 @@ +/*【例12-1】从2开始依次找出500个素数,将这些素数存入文本文件prime.txt中。*/ + +/* 生成素数文件*/ +#include + +using namespace std; + +int prime(int n); /* 例5-5中函数prime()的声明 */ + +int main(void) { + FILE *fp; /* 1.定义文件指针 */ + int n = 2, count = 0; + + if ((fp = fopen("prime.txt", "w")) == NULL) { /* 2.打开文件 */ + printf("File open error!\n"); + exit(0); + } + + while (count < 500) { + if (prime(n) != 0) { + count++; + fprintf(fp, "%d ", n); /* 3.文件处理(写入) */ + } + n++; + } + if (fclose(fp)) { /* 4.关闭文件 */ + printf("Can not close the file!\n"); + exit(0); + } + + return 0; +} + +/* 判断素数的函数 */ +int prime(int m) { + int i, limit; + + if (m <= 1) { /* 小于等于1的数不是素数 */ + return 0; + } + else if (m == 2) { /* 2是素数 */ + return 1; + } + else { /* 其他情况:大于2的正整数 */ + limit = sqrt(m) + 1; + for (i = 2; i <= limit; i++) { + if (m % i == 0) { + return 0; /* 若m能被某个i整除,则m不是素数,返回0 */ + } + } + /* 若循环正常结束,说明m不能被任何一个i整除,则m是素数,返回1 */ + return 1; + } +} diff --git a/Miscellaneous/quick_sort.cpp b/Miscellaneous/quick_sort.cpp new file mode 100644 index 0000000..52b7861 --- /dev/null +++ b/Miscellaneous/quick_sort.cpp @@ -0,0 +1,62 @@ +#include + +using namespace std; + +void quick_sort(int *arr, int left, int right) { + if (left >= right) { + return; + } + + int pivot = arr[(left + right) / 2]; + int i = left - 1; + int j = right + 1; + + while (1) { + do { + i++; + } while (arr[i] < pivot); + + do { + j--; + } while (arr[j] > pivot); + + if (i >= j) { + break; + } + + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + + quick_sort(arr, left, j); + quick_sort(arr, j + 1, right); +} + +int main() { + int n; + + cout << "请输入将要被排序的整数的个数:"; + + cin >> n; + + cout << "请输入将要被排序的整数,其间以空格隔开:"; + + int arr[n]; + + for (int i = 0; i < n; i++) { + cin >> arr[i]; + } + + quick_sort(arr, 0, n - 1); + + cout << "经过快速排序后的结果是:"; + + for (int i = 0; i < n; i++) { + cout << arr[i] << ' '; + } + + cout << '\n'; + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/rand_number.cpp b/Miscellaneous/rand_number.cpp new file mode 100644 index 0000000..ede3c4a --- /dev/null +++ b/Miscellaneous/rand_number.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +double average(const vector &v) { + if (v.empty()) { + return 0; + } + + double sum = 0; + for (auto &&i : v) { + sum += i; + } + + return sum / v.size(); +} + +int main() { + int cnt = 1; + vector v; + while (true) { + srand(time(nullptr)); + int rand_num = rand() % 100 + 1; + cout << "Random number" << ' ' << cnt << ": " << rand_num << endl; + v.push_back(rand_num); + cout << "Average: " << average(v) << endl; + cnt++; + this_thread::sleep_for(chrono::seconds(1)); + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/second_rank_pointer.cpp b/Miscellaneous/second_rank_pointer.cpp new file mode 100644 index 0000000..122b548 --- /dev/null +++ b/Miscellaneous/second_rank_pointer.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +int main(int argc, char *argv[]) { + int i1 = 0, i2 = 1; + int j1 = 0, j2 = 0; + + int a[][4] = { + { 1, 2, 3, 4 }, + { 5, 6, 7, 8 }, + { 9, 10, 11, 12 } + }; + + int *p1 = *(a + i1) + j1; + int *p2 = *(a + i2) + j2; + int *p3 = *(a + 1); + int *p4 = a[1]; + int d = p2 - p1; + + int e1 = *p1; + int e2 = *(*(a + i1) + j1); + int e3 = a[i1][j1]; + + printf("%p: %d\n", p1, e1); + printf("%p: %d\n", p2, e2); + printf("p3=%p, p4=%p\n", p3, p4); + printf("e1 = %d, e2 = %d, e3 = %d\n", e1, e2, e3); + printf("d = %d\n", d); + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/selection_sort.cpp b/Miscellaneous/selection_sort.cpp new file mode 100644 index 0000000..d1be1f1 --- /dev/null +++ b/Miscellaneous/selection_sort.cpp @@ -0,0 +1,44 @@ +#include + +using namespace std; + +void swap(int *a, int *b); + +void selection_sort(int *a, int len); + +int main(int argc, char const *argv[]) { + int m; + scanf("%d", &m); + int *a = (int *)malloc(m * sizeof(int)); + for (int i = 0; i < m; i++) { + scanf("%d", &a[i]); + } + + selection_sort(a, m); + + for (int i = 0; i < m; i++) { + printf("%d ", a[i]); + } + + free(a); + + return 0; +} + +void selection_sort(int *arr, int len) { + int i, j; + + for (i = 0; i < len - 1; i++) { + int max = i; + for (j = i + 1; j < len; j++) + if (arr[j] > arr[max]) + max = j; + swap(&arr[max], &arr[i]); + } +} + +void swap(int *a, int *b) { + int temp = *a; + *a = *b; + *b = temp; +} diff --git a/Miscellaneous/sizeof.cpp b/Miscellaneous/sizeof.cpp new file mode 100644 index 0000000..8989df3 --- /dev/null +++ b/Miscellaneous/sizeof.cpp @@ -0,0 +1,12 @@ +#include + +using namespace std; + +int main(void) { + printf("sizeof(char) = %ld\n", sizeof(char)); + printf("sizeof(short) = %ld\n", sizeof(short)); + printf("sizeof(int) = %zu\n", sizeof(int)); + printf("sizeof(long) = %zu\n", sizeof(long)); + printf("sizeof(long long) = %ld\n", sizeof(long long)); + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/statistics.cpp b/Miscellaneous/statistics.cpp new file mode 100644 index 0000000..20365f1 --- /dev/null +++ b/Miscellaneous/statistics.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +#define NUMBER 10 + +int main(void) { + int cnt[NUMBER]; + int x; + + for (int i = 0; i < NUMBER; i++) { + cnt[i] = 0; + } + + scanf("%d", &x); + + while (x != -1) { + if (x >= 0 && x <= 9) { + cnt[x]++; + } + scanf("%d", &x); + } + + for (int i = 0; i < NUMBER; i++) { + printf("%d: %d\n", i, cnt[i]); + } + return 0; +} diff --git a/Miscellaneous/string_sort.cpp b/Miscellaneous/string_sort.cpp new file mode 100644 index 0000000..83e3981 --- /dev/null +++ b/Miscellaneous/string_sort.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +int main(int argc, char **argv) { + char a[5][999]; + + for (int i = 0; i < 5; i++) { + scanf("%s", a[i]); + } + + for (int i = 0; i < 4; i++) { + char temp[999]; + for (int j = 0; j < 4 - i; j++) { + if (strcmp(a[j], a[j + 1]) > 0) { + strcpy(temp, a[j]); + strcpy(a[j], a[j + 1]); + strcpy(a[j + 1], temp); + } + } + } + + for (int i = 0; i < 5; i++) { + printf("%s\n", a[i]); + } + + return 0; +} \ No newline at end of file diff --git a/Miscellaneous/sum.cpp b/Miscellaneous/sum.cpp new file mode 100644 index 0000000..46064c1 --- /dev/null +++ b/Miscellaneous/sum.cpp @@ -0,0 +1,20 @@ +#include + +using namespace std; + +int main(void) { + int n; + double sum = 0.0; + double sign = 1.0; + + scanf("%d", &n); + + for (int i = 1; i <= n; i++) { + sum += sign / i; + sign = -sign; + } + + printf("f (%d) = %f\n", n, sum); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/1/1.cpp b/Practical-Teaching/Data-Sructure/1/1.cpp new file mode 100644 index 0000000..26af438 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/1/1.cpp @@ -0,0 +1,128 @@ +// 预编译命令 +#include +#include + +// 数据结构定义 +typedef struct +{ + int num; + char name[20]; + int score[3]; + int ave; +} Student; // 结构体类型定义 + +// 函数声明 +int menu_select(); +void input(Student s[5]); +void output(Student s[5], int n); +void average(Student s[5]); +void sort(Student s[5]); + +// 主函数 +int main() { + Student stu[5]; // 准备实参 + for (;;) { + switch (menu_select()) { + case 1: + printf("请输入5位同学的信息\n"); + input(stu); // 函数调用 + break; + case 2: + printf("输出5位同学的信息\n"); + output(stu, 5); + break; + case 3: + average(stu); + printf("平均分已经求过\n"); + break; + case 4: + sort(stu); + printf("按照平均分由高到低排序已经完成\n"); + break; + case 5: + printf("输出前3名同学的信息\n"); + sort(stu); // 输出前3名之前先排序 + output(stu, 3); + break; + case 0: + printf("谢谢使用本软件\n"); + exit(0); + } + } + return 0; +} + +// 菜单函数 +int menu_select() { + int sn; + printf("\n1.输入5位同学的信息\n"); + printf("2.输出5位同学的信息\n"); + printf("3.求平均分\n"); + printf("4.排序\n"); + printf("5.输出前三名\n"); + printf("0.结束\n"); + printf("Input 0~5:"); + for (;;) { + scanf("%d", &sn); + if (sn < 0 || sn > 5) + printf("\n输入错误,重选0~5:"); + else + break; + } + return sn; +} + +// 输入函数 +void input(Student s[5]) { + int i, j; + for (i = 0; i < 5; i++) { + scanf("%d", &s[i].num); + scanf("%s", s[i].name); + for (j = 0; j < 3; j++) { + scanf("%d", &s[i].score[j]); + } + } +} + +// 输出函数 +void output(Student s[5], int n) // 增加一个参数n,为输出元素的个数 +{ + int i, j; + for (i = 0; i < n; i++) { + printf("%d\t", s[i].num); + printf("%s\t", s[i].name); + for (j = 0; j < 3; j++) { + printf("%d\t", s[i].score[j]); + } + printf("%d\t", s[i].ave); + printf("\n"); + } +} + +// 求平均分 +void average(Student s[5]) { + int i, j, sum; + for (i = 0; i < 5; i++) { + sum = 0; + for (j = 0; j < 3; j++) { + sum += s[i].score[j]; + } + s[i].ave = sum / 3; + } +} + +// 冒泡排序 +void sort(Student s[5]) { + average(s); // 排序之前应该先求过平均分 + int i, j; + Student t; + for (i = 4; i > 0; i--) { + for (j = 0; j < i; j++) { + if (s[j].ave < s[j + 1].ave) { + t = s[j]; + s[j] = s[j + 1]; + s[j + 1] = t; + } + } + } +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/1/输入学生初始化信息.txt b/Practical-Teaching/Data-Sructure/1/输入学生初始化信息.txt new file mode 100644 index 0000000..97e4e13 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/1/输入学生初始化信息.txt @@ -0,0 +1,5 @@ +111 aaa 88 88 88 +222 bbb 66 66 66 +333 ccc 99 99 99 +444 ddd 55 55 55 +555 fff 77 77 77 \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/2/2.cpp b/Practical-Teaching/Data-Sructure/2/2.cpp new file mode 100644 index 0000000..f26a540 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/2/2.cpp @@ -0,0 +1,206 @@ +// 预编译命令 +#include +#include +#define OK 1 +#define ERROR 0 +#define OVERFLOW -2 +#define LIST_INIT_SIZE 10 // 表存储空间的初始分配量 +#define LISTINCREMENT 2 // 线性表存储空间的分配增量 + +// 数据结构 +typedef int Status; +typedef int ElemType; +typedef struct +{ + ElemType *elem; // 存储空间基址 + int length; // 当前长度 + int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位) +} SqList; + +// 函数声明 +int menu_select(); +Status InitList_Sq(SqList &L); +Status CreatList_Sq(SqList &L, int n); +void PrintList_Sq(SqList L); +Status ListInsert_Sq(SqList &L, int i, ElemType e); +Status ListDelete_Sq(SqList &L, int i, ElemType &e); +int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType)); +Status equal(ElemType x, ElemType y); + +// 主函数 +int main() { + SqList L; + Status s; + int n, i, e; + for (;;) { + switch (menu_select()) { + case 1: + s = InitList_Sq(L); + if (s) + printf("初始化成功\n"); + else + printf("初始化失败\n"); + break; + case 2: + printf("输入线性表的长度:"); + scanf("%d", &n); + s = CreatList_Sq(L, n); + if (s) + printf("创建成功\n"); + else + printf("创建失败\n"); + break; + case 3: + PrintList_Sq(L); + break; + case 4: + printf("请输入插入的位序:"); + scanf("%d", &i); + printf("请输入插入的新元素的值:"); + scanf("%d", &e); + s = ListInsert_Sq(L, i, e); + if (s) + printf("插入成功!\n"); + else + printf("插入失败!\n"); + break; + case 5: + printf("输入删除的位序:"); + scanf("%d", &i); + s = ListDelete_Sq(L, i, e); + if (s) + printf("删除了元素%d成功\n", e); + else + printf("删除失败\n"); + break; + break; + case 6: + printf("请输入查找的元素的值:"); + scanf("%d", &e); + i = LocateElem_Sq(L, e, equal); // 指向函数类型的指针作形参,实参用同类型的函数名equal + if (i) + printf("%d的逻辑位序是%d\n", e, i); + else + printf("查找失败!\n"); + break; + case 0: + printf("程序结束,谢谢使用!\n\n"); + exit(0); + } + } + return 0; +} + +// 菜单函数 +int menu_select() { + int sn; + printf("\n显示菜单\n"); + printf("1.初始化\n"); + printf("2.创建\n"); + printf("3.显示\n"); + printf("4.插入\n"); + printf("5.删除\n"); + printf("6.查找\n"); + printf("0.退出\n"); + printf("输入 0-6:"); + for (;;) { + scanf("%d", &sn); + if (sn < 0 || sn > 6) + printf("\n输入错误,重选0-6:"); + else + break; + } + return sn; +} + +// 初始化空的动态顺序表函数 +Status InitList_Sq(SqList &L) { + L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); + if (!L.elem) + return (OVERFLOW); + L.length = 0; + L.listsize = LIST_INIT_SIZE; + return OK; +} + +// 创建动态顺序表(输入n个元素) +Status CreatList_Sq(SqList &L, int n) { + int i; + if (n > L.listsize) + return (ERROR); + printf("输入%d个整型数:", n); + for (i = 1; i <= n; i++) { + scanf("%d", &L.elem[i - 1]); // 类C代码中无格式输入字符串,需要补充 + } + L.length = n; + return OK; +} + +// 输出顺序表元素 +void PrintList_Sq(SqList L) { + int i; + for (i = 1; i <= L.length; i++) { + printf("%d\t", L.elem[i - 1]); + } + printf("\n"); +} + +// 插入新元素e到第i个位序 +Status ListInsert_Sq(SqList &L, int i, ElemType e) { + ElemType *newbase, *q, *p; // 类C代码中不含变量定义,需要补充 + if (i < 1 || i > L.length + 1) // 插入位置不合法 + return ERROR; + if (L.length >= L.listsize) // 当前储存空间不足 + { + newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType)); + if (!newbase) + exit(OVERFLOW); // 存储位置失败 + L.elem = newbase; // 新基址 + L.listsize += LISTINCREMENT; // 增加存储位置 + } + q = &(L.elem[i - 1]); // 要插入的位置 + for (p = &(L.elem[L.length - 1]); p >= q; --p) + *(p + 1) = *p; // 插入位置之后的元素右移 + *q = e; // 插入e + ++L.length; + return OK; // 表长增加1 +} // ListInsert_Sq + +// 删除第i个元素 +Status ListDelete_Sq(SqList &L, int i, ElemType &e) { + ElemType *p, *q; // 补出变量定义 + if ((i < 1) || (i > L.length)) + return ERROR; + p = &(L.elem[i - 1]); + e = *p; + q = L.elem + L.length - 1; + e = *p; + q = L.elem + L.length - 1; + for (++p; p <= q; ++p) + *(p - 1) = *p; + --L.length; + return OK; +} + +// 查找给定值的位序 +int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType) /*指向函数类型的指针作形参*/) { + ElemType *p; + int i; // 补出变量定义 + i = 1; // 当前元素的逻辑位序 + p = L.elem; // 当前元素的物理地址 + while (i <= L.length && !(*compare)(*(p++), e)) + ++i; + if (i <= L.length) + return i; + else + return 0; +} // LocateElem_Sq + +// 判断两个数据元素是否相等的函数 +Status equal(ElemType x, ElemType y) // 为LocateElem_Sq函数准备第三个实参 +{ + if (x == y) + return OK; + else + return ERROR; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/3/3.cpp b/Practical-Teaching/Data-Sructure/3/3.cpp new file mode 100644 index 0000000..adbea7e --- /dev/null +++ b/Practical-Teaching/Data-Sructure/3/3.cpp @@ -0,0 +1,247 @@ +// 预编译命令 +#include +#include + +#define OK 1 +#define ERROR 0 +#define OVERFLOW -2 + +// 数据结构 +typedef int Status; +typedef int ElemType; +typedef struct LNode +{ + ElemType data; + struct LNode *next; +} LNode, *LinkList; + +// 函数声明 +int menu_select(); +int menu_select(); +void CreateList_L(LinkList &L, int n); +void PrintList_L(LinkList L); +Status GetElem_L(LinkList &L, int i, ElemType &e); +Status ListInsert_L(LinkList &L, int i, ElemType e); +Status ListDelete_L(LinkList &L, int i, ElemType &e); +int LocateElem_L(LinkList L, ElemType e); + +// 主函数 +int main() +{ + LinkList L; + int n, i, e, k; + for (;;) + { + switch (menu_select()) + { + case 1: + printf("请输入元素的个数:"); + scanf("%d", &n); + CreateList_L(L, n); + printf("创建完成\n"); + break; + case 2: + PrintList_L(L); + break; + case 3: + printf("请输入要查找的元素的位序:"); + scanf("%d", &i); + if (GetElem_L(L, i, e) == OK) // 调用取元素函数,如果成功,返回元素值给 e + { + printf("第%d个元素的值是%d\n", i, e); + } + else // 如果失败,输出错误信息 + { + printf("查找失败,不存在第%d个元素\n", i); + } + break; + case 4: + printf("请输入要插入的元素的位序和值,用空格隔开:"); + scanf("%d %d", &i, &e); + if (ListInsert_L(L, i, e) == OK) // 调用插入函数,如果成功,输出插入成功信息 + { + printf("插入成功\n"); + } + else // 如果失败,输出错误信息 + { + printf("插入失败,插入位置不合法\n"); + } + break; + case 5: + printf("请输入要删除的元素的位序:"); + scanf("%d", &i); + if (ListDelete_L(L, i, e) == OK) // 调用删除函数,如果成功,返回删除的元素值给 e,并输出删除成功信息 + { + printf("删除成功,删除的元素值是%d\n", e); + } + else // 如果失败,输出错误信息 + { + printf("删除失败,删除位置不合法\n"); + } + break; + case 6: + printf("请输入要查找的元素的值:"); + scanf("%d", &e); + k = LocateElem_L(L, e); // 调用查找函数(已知元素找位序),返回位序给 k + if (k != 0) // 如果 k 不为 0,说明找到了元素 e,并输出其位序 + { + printf("找到了元素%d,它的位序是%d\n", e, k); + } + else // 如果 k 为 0,说明没有找到元素 e,并输出查找失败信息 + { + printf("查找失败,不存在元素%d\n", e); + } + + break; + case 0: + printf("程序结束,谢谢使用!\n\n"); + exit(0); + } + } + return 0; +} + +int menu_select() +{ + int sn; + printf("\n显示菜单\n"); + printf("1.创建\n"); + printf("2.显示\n"); + printf("3.取元素\n"); + printf("4.插入\n"); + printf("5.删除\n"); + printf("6.查找\n"); + printf("0.退出\n"); + printf("输入 0-6:"); + for (;;) + { + scanf("%d", &sn); + if (sn < 0 || sn > 6) + printf("\n输入错误,重选0-6:"); + else + break; + } + return sn; +} + +// 创建单链表,头插法,已知线性表的长度 +void CreateList_L(LinkList &L, int n) +{ + LinkList p; + int i; + L = (LinkList)malloc(sizeof(LNode)); + L->next = NULL; + printf("请逆序输入%d个元素:\n", n); + for (i = n; i >= 1; i--) + { + p = (LinkList)malloc(sizeof(LNode)); + scanf("%d", &p->data); // 格式输入字符串补出来 + p->next = L->next; + L->next = p; + } +} + +// 输出单链表 +void PrintList_L(LinkList L) +{ + LinkList p; + p = L->next; + printf("输出链表中的元素:\n"); + while (p) + { + printf("%d\t", p->data); + p = p->next; + } + printf("\n"); +} + +// 取元素函数 +Status GetElem_L(LinkList &L, int i, ElemType &e) +{ + // 在单链表 L 中查找第 i 个元素,并将其值赋给 e + LinkList p; // 定义一个指针 p + int j; // 定义一个计数器 j + p = L->next; // 让 p 指向链表 L 的第一个结点 + j = 1; // 初始化 j 为 1 + while (p && j < i) // p 不为空且计数器 j 还没有等于 i 时,循环继续 + { + p = p->next; // 让 p 指向下一个结点 + j++; // 让 j 增加 1 + } + if (!p || j > i) // 如果 p 为空或者 j 大于 i,说明第 i 个元素不存在 + { + return ERROR; // 返回错误标志 + } + e = p->data; // 取出第 i 个元素的数据,赋给 e + return OK; // 返回成功标志 +} + +// 插入函数 +Status ListInsert_L(LinkList &L, int i, ElemType e) +{ + // 在单链表 L 中的第 i 个位置插入新的元素 e + LinkList p, s; // 定义两个指针 p 和 s + int j; // 定义一个计数器 j + p = L; // 让 p 指向链表 L 的头结点 + j = 0; // 初始化 j 为 0 + while (p && j < i - 1) // 寻找第 i-1 个结点,p 指向该结点 + { + p = p->next; + j++; + } + if (!p || j > i - 1) // 如果 p 为空或者 j 大于 i-1,说明插入位置不合法 + { + return ERROR; // 返回错误标志 + } + s = (LinkList)malloc(sizeof(LNode)); // 分配一个新的结点 s + s->data = e; // 将新元素 e 赋给 s 的数据域 + s->next = p->next; // 将 s 的指针域指向 p 的后继结点 + p->next = s; // 将 p 的指针域指向 s 结点 + return OK; // 返回成功标志 +} + +// 删除函数 +Status ListDelete_L(LinkList &L, int i, ElemType &e) +{ + // 在单链表 L 中删除第 i 个元素,并用 e 返回其值 + LinkList p, q; // 定义两个指针 p 和 q + int j; // 定义一个计数器 j + p = L; // 让 p 指向链表 L 的头结点 + j = 0; // 初始化 j 为 0 + while (p->next && j < i - 1) // 寻找第 i-1 个结点,p 指向该结点,且保证 p 的后继不为空(即第 i 个结点存在) + { + p = p->next; + j++; + } + if (!(p->next) || j > i - 1) // 如果 p 的后继为空或者 j 大于 i-1,说明删除位置不合法 + { + return ERROR; // 返回错误标志 + } + q = p->next; // 让 q 指向要删除的结点(即第 i 个结点) + p->next = q->next; // 将 q 的后继赋给 p 的后继(即相当于断开了 q 结点) + e = q->data; // 将 q 结点的数据赋给 e(用于返回) + free(q); // 释放 q 结点的空间 + return OK; // 返回成功标志 +} + +// 查找函数(已知元素找位序) +int LocateElem_L(LinkList L, ElemType e) +{ + LinkList p; + int i; + p = L->next; + i = 1; + while (p && p->data != e) // 从第一个结点开始,遍历链表,直到找到元素 e 或者链表结束 + { + p = p->next; + i++; + } + if (p) // 如果找到了元素 e,返回其位序 i + { + return i; + } + else // 如果没有找到元素 e,返回 0 + { + return 0; + } +} diff --git a/Practical-Teaching/Data-Sructure/4/4.cpp b/Practical-Teaching/Data-Sructure/4/4.cpp new file mode 100644 index 0000000..6dd6dcb --- /dev/null +++ b/Practical-Teaching/Data-Sructure/4/4.cpp @@ -0,0 +1,175 @@ +// 预编译命令 +#include +#include +#include "stack.h" + +#define OK 1 +#define ERROR 0 +#define OVERFLOW -2 +#define STACK_INIT_SIZE 10 // 顺序栈存储空间的初始分配量 +#define STACKINCREMENT 2 // 顺序栈存储空间的分配增量 + +// 输出顺序栈的元素 +void PrintStack(SqStack S) { + SElemType *p; + for (p = S.base; p < S.top; p++) { + printf("%d\t", *p); + } +} + +// 输入n个元素入栈 +Status CreateStack(SqStack &S, int n) { + int i; + if (n > S.stacksize) + return (ERROR); + printf("输入%d个整型数:", n); + for (i = 1; i <= n; i++) { + scanf("%d", S.top++); + } + return OK; +} + +// 菜单函数 +int menu_select() { + int sn; + printf("\n显示菜单\n"); + printf("1.初始化栈\n"); + printf("2.创建栈\n"); + printf("3.显示栈\n"); + printf("4.取栈顶元素\n"); + printf("5.入栈\n"); + printf("6.出栈\n"); + printf("7.判断栈空否\n"); + printf("8.销毁栈\n"); + printf("9.数制转换\n"); + // printf("10.括号匹配\n"); + printf("0.退出\n"); + printf("输入 0-8:"); + for (;;) { + scanf("%d", &sn); + if (sn < 0 || sn > 9) + printf("\n输入错误,重选0-8:"); + else + break; + } + return sn; +} + +void Conversion() { + SqStack S; + InitStack(S); + int N; + printf("输入要转换的十进制数:"); + scanf("%d", &N); + while (N) { + Push(S, N % 8); + N /= 8; + } + printf("转换后的八进制数为:"); + while (!StackEmpty(S)) { + int e; + Pop(S, e); + printf("%d", e); + } + printf("\n"); +} + +// void BracketMatch() { +// SqStack S; +// InitStack(S); +// char c; +// printf("输入括号序列:"); +// while ((c = getchar()) != '\n') { +// if (c == '(') +// Push(S, c); +// else if (c == ')') { +// if (StackEmpty(S)) { +// printf("括号不匹配\n"); +// return; +// } +// Pop(S, c); +// } +// } +// if (StackEmpty(S)) +// printf("括号匹配\n"); +// else +// printf("括号不匹配\n"); +// } + +// 主函数 +int main() { + SqStack S; + Status s; + int n; + SElemType e; + for (;;) { + switch (menu_select()) { + case 1: + s = InitStack(S); + if (s) + printf("初始化成功\n"); + else + printf("初始化失败\n"); + break; + case 2: + printf("输入栈的长度:"); + scanf("%d", &n); + s = CreateStack(S, n); + if (s) + printf("创建成功\n"); + else + printf("创建失败\n"); + break; + case 3: + PrintStack(S); + break; + case 4: + s = GetTop(S, e); + if (s) + printf("栈顶元素为%d\n", e); + else + printf("栈为空,取栈顶元素失败\n"); + break; + case 5: + printf("输入入栈的元素值:"); + scanf("%d", &e); + s = Push(S, e); + if (s) + printf("%d入栈成功\n", e); + else + printf("入栈失败\n"); + break; + case 6: + s = Pop(S, e); + if (s) + printf("%d出栈成功\n", e); + else + printf("栈为空,出栈失败\n"); + break; + case 7: + s = StackEmpty(S); + if (s) + printf("栈为空\n"); + else + printf("栈不为空\n"); + break; + case 8: + s = DestroyStack(S); + if (s) + printf("销毁栈成功\n"); + else + printf("销毁栈失败\n"); + break; + case 9: + Conversion(); + break; + // case 10: + // BracketMatch(); + // break; + case 0: + printf("程序结束,谢谢使用\n\n"); + exit(0); + } + } + return 0; +} diff --git a/Practical-Teaching/Data-Sructure/4/stack.h b/Practical-Teaching/Data-Sructure/4/stack.h new file mode 100644 index 0000000..c34064e --- /dev/null +++ b/Practical-Teaching/Data-Sructure/4/stack.h @@ -0,0 +1,74 @@ +// 预编译命令 +#include +#include +#define OK 1 +#define ERROR 0 +#define OVERFLOW -2 +#define STACK_INIT_SIZE 10 // 顺序栈存储空间的初始分配量 +#define STACKINCREMENT 2 // 顺序栈存储空间的分配增量 + +// 数据结构 +typedef int Status; +typedef int SElemType; // 完成数制转换 +// typedef char SElemType; //完成括号匹配 +typedef struct { + SElemType *base; // 存储空间基址 + SElemType *top; // 存储空间基址 + int stacksize; // 当前分配的存储容量(以sizeof(ElemType)为单位) +} SqStack; + +// 构造一个最大空间为 STACK_INIT_SIZE的空顺序栈S +Status InitStack(SqStack &S) { + + S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); + if (!S.base) + exit(OVERFLOW); // 存储分配失败 + S.top = S.base; + S.stacksize = STACK_INIT_SIZE; + return OK; +} + +// 栈不空,则用e返回栈顶元素 +Status GetTop(SqStack S, SElemType &e) { + if (S.top == S.base) + return ERROR; + e = *(S.top - 1); + return OK; +} + +// 给定值e入栈 +Status Push(SqStack &S, SElemType e) { + if (S.top - S.base >= S.stacksize) { + S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType)); + S.top = S.base + S.stacksize; + S.stacksize += STACKINCREMENT; + } + *S.top++ = e; + return OK; +} + +// 若栈不空,则删除S的栈顶元素, +// 用 e 返回其值,并返回OK; +// 否则返回ERROR +Status Pop(SqStack &S, SElemType &e) { + if (S.top == S.base) + return ERROR; + e = *--S.top; + return OK; +} + +// 判断栈空否 +Status StackEmpty(SqStack S) { + if (S.top == S.base) + return OK; + else + return ERROR; +} + +// 销毁栈 +Status DestroyStack(SqStack &S) { + if (!S.base) + return ERROR; + free(S.base); + return OK; +} diff --git a/Practical-Teaching/Data-Sructure/Big/1/线性表1.cpp b/Practical-Teaching/Data-Sructure/Big/1/线性表1.cpp new file mode 100644 index 0000000..20eeb2f --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/1/线性表1.cpp @@ -0,0 +1,95 @@ +#include + +#define MAXSIZE 50 + +typedef struct +{ + int data[MAXSIZE]; + int size; +} seqlist; + +void seqlist_init(seqlist *list) { + list->size = 0; +} + +void insert(seqlist *list, int position, int data) { + if (list->size == MAXSIZE) { + printf("seqlist is full\n"); + return; + } + if (position < 0 || position > list->size) { + printf("position is out of range\n"); + return; + } + for (int i = list->size - 1; i >= position; i--) { + list->data[i + 1] = list->data[i]; + } + list->data[position] = data; + list->size++; +} + +void delete(seqlist *list, int position) { + if (list->size == MAXSIZE) { + printf("seqlist is full\n"); + return; + } + if (position < 0 || position >= list->size) { + printf("position is out of range\n"); + return; + } + for (int i = position; i <= list->size - 1; i++) { + list->data[i] = list->data[i + 1]; + } + list->size--; +} + +int get(seqlist *list, int position) { + if (position < 0 || position >= list->size) { + printf("获取位置不合法\n"); + return -1; // 返回一个特殊值表示错误 + } + + return list->data[position]; +} + +int search(seqlist *list, int data) { + for (int i = 0; i < list->size; i++) { + if (list->data[i] == data) + return i; + } + return -1; +} +void printSeqList(seqlist *list) { + printf("顺序表元素: "); + for (int i = 0; i < list->size; i++) { + printf("%d ", list->data[i]); + } + printf("\n"); +} +int main() { + + seqlist myList; + seqlist_init(&myList); + + insert(&myList, 0, 1); + insert(&myList, 1, 2); + insert(&myList, 2, 3); + + printSeqList(&myList); + + delete (&myList, 1); + + printSeqList(&myList); + + int value = get(&myList, 1); + if (value != -1) { + printf("位置1的元素为: %d\n", value); + } + + int position = search(&myList, 3); + if (position != -1) { + printf("元素3的位置为: %d\n", position); + } + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/1/线性表2.cpp b/Practical-Teaching/Data-Sructure/Big/1/线性表2.cpp new file mode 100644 index 0000000..c91a093 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/1/线性表2.cpp @@ -0,0 +1,185 @@ +#include +#include + +typedef struct Node { + int data; + struct Node *next; +} Node; + +Node *creat_front(int num[], int lenth) { + Node *head = NULL; + for (int i = 0; i < lenth; i++) { + Node *new_node = (Node *)malloc(sizeof(Node)); + if (new_node == NULL) { + printf("Failed to allocate\n"); + exit(1); + } + new_node->data = num[i]; + new_node->next = head; + head = new_node; + } + return head; +} + +Node *creat_back(int num[], int lenth) { + Node *head = NULL; + Node *back = NULL; + for (int i = 0; i < lenth; i++) { + Node *new_node = (Node *)malloc(sizeof(Node)); + if (new_node == NULL) { + printf("Failed to allocate\n"); + exit(1); + } + new_node->data = num[i]; + new_node->next = NULL; + if (head == NULL) { + head = new_node; + back = new_node; + } + else { + back->next = new_node; + back = new_node; + } + } + return head; +} + +int get_list(Node *head, int position) { + Node *q = head; + int i = 0; + while (q != NULL) { + if (i == position) { + return q->data; + } + else { + q = q->next; + i++; + } + } + if (q == NULL) + printf("position is out of range and fail to get data!\n"); + free(q); + return -1; +} + +Node *insert(Node *head, int position, int data) { + Node *newNode = (Node *)malloc(sizeof(Node)); + if (newNode == NULL) { + printf("fail to allocate!\n"); + exit(1); + } + newNode->data = data; + if (position == 0) { + newNode->next = head; + head = newNode; + } + else { + Node *current = head; + int index = 0; + + while (current != NULL && index < position - 1) { + current = current->next; + index++; + } + + if (current != NULL) { + newNode->next = current->next; + current->next = newNode; + } + else { + printf("插入位置不合法\n"); + free(newNode); + } + } + + return head; +} + +int findElement(Node *head, int value) { + Node *current = head; + int i = 0; + + while (current != NULL) { + if (current->data == value) { + return i; + } + + current = current->next; + i++; + } + + exit(i); +} +Node *deleteElement(Node *head, int position) { + if (head == NULL) { + printf("链表为空\n"); + return NULL; + } + + Node *temp; + if (position == 0) { + temp = head; + head = head->next; + } + else { + Node *current = head; + int index = 0; + + while (current != NULL && index < position - 1) { + current = current->next; + index++; + } + + if (current != NULL && current->next != NULL) { + temp = current->next; + current->next = current->next->next; + } + else { + printf("删除位置不合法\n"); + return head; + } + } + + free(temp); + return head; +} +void printList(Node *head) { + Node *current = head; + + while (current != NULL) { + printf("%d ", current->data); + current = current->next; + } + + printf("\n"); +} + +int main() { + int a[] = { 5, 6, 8, 9, 1 }; + Node *myList = creat_front(a, 5); + printf("List after front insertion: "); + printList(myList); + free(myList); + + myList = creat_back(a, 5); + printf("List after end insertion: "); + printList(myList); + + int valueAtIndex2 = get_list(myList, 2); + printf("Value at index 2: %d\n", valueAtIndex2); + + int searchResult = findElement(myList, 8); + printf("Index of value 8: %d\n", searchResult); + + myList = insert(myList, 2, 10); + printf("List after insertion at index 2: "); + printList(myList); + + myList = deleteElement(myList, 3); + printf("List after deletion at index 3: "); + printList(myList); + + free(myList); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/1/线性表3.cpp b/Practical-Teaching/Data-Sructure/Big/1/线性表3.cpp new file mode 100644 index 0000000..00e5717 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/1/线性表3.cpp @@ -0,0 +1,84 @@ +#include + +// 定义多项式的项 +typedef struct +{ + int coefficient; // 系数 + int exponent; // 指数 +} Term; + +// 函数声明 +void addPolynomials(Term poly1[], int n1, Term poly2[], int n2, Term result[], int *nResult); + +int main() { + int n1, n2; + + // 输入第一个多项式的项数 + printf("第一个多项式\n项数:"); + scanf("%d", &n1); + + // 输入第一个多项式的各项系数和指数 + Term poly1[n1]; + for (int i = 0; i < n1; i++) { + printf("第%d项系数和指数:", i + 1); + scanf("%d %d", &poly1[i].coefficient, &poly1[i].exponent); + } + + // 输入第二个多项式的项数 + printf("\n第二个多项式\n项数:"); + scanf("%d", &n2); + + // 输入第二个多项式的各项系数和指数 + Term poly2[n2]; + for (int i = 0; i < n2; i++) { + printf("第%d项系数和指数:", i + 1); + scanf("%d %d", &poly2[i].coefficient, &poly2[i].exponent); + } + + // 计算两个多项式的和 + int nResult = n1 + n2; + Term result[nResult]; + addPolynomials(poly1, n1, poly2, n2, result, &nResult); + + // 输出结果 + printf("\n和多项式的各项为:\n"); + for (int i = 0; i < nResult; i++) { + printf("第%d项,系数:%d,指数:%d\n", i + 1, result[i].coefficient, result[i].exponent); + } + + return 0; +} + +// 实现多项式相加的函数 +void addPolynomials(Term poly1[], int n1, Term poly2[], int n2, Term result[], int *nResult) { + int i = 0, j = 0, k = 0; + + // 循环遍历两个多项式的项 + while (i < n1 && j < n2) { + // 比较当前项的指数大小 + if (poly1[i].exponent > poly2[j].exponent) { + result[k++] = poly1[i++]; + } + else if (poly1[i].exponent < poly2[j].exponent) { + result[k++] = poly2[j++]; + } + else { + // 指数相等时,系数相加 + result[k].exponent = poly1[i].exponent; + result[k++].coefficient = poly1[i++].coefficient + poly2[j++].coefficient; + } + } + + // 处理多项式1剩余的项 + while (i < n1) { + result[k++] = poly1[i++]; + } + + // 处理多项式2剩余的项 + while (j < n2) { + result[k++] = poly2[j++]; + } + + // 更新结果多项式的项数 + *nResult = k; +} diff --git a/Practical-Teaching/Data-Sructure/Big/1/线性表4.cpp b/Practical-Teaching/Data-Sructure/Big/1/线性表4.cpp new file mode 100644 index 0000000..5fd4f91 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/1/线性表4.cpp @@ -0,0 +1,193 @@ +#include +#include +#include + +// 学生结构体 +typedef struct +{ + int id; + char name[5]; +} Student; + +// 链表节点结构体 +typedef struct Node { + Student student; + struct Node *next; +} Node; + +// 链表结构体 +typedef struct +{ + Node *head; +} LinkedList; + +// 函数声明 +void initList(LinkedList *list); +void insertStudent(LinkedList *list, Student student); +void printList(LinkedList list); +Node *findStudentById(LinkedList list, int id); +void deleteStudentById(LinkedList *list, int id); +void clearList(LinkedList *list); + +int main() { + LinkedList studentList; + initList(&studentList); + + int choice; + do { + // 用户菜单 + printf("\n学生管理系统菜单:\n"); + printf("1. 添加学生\n"); + printf("2. 删除学生\n"); + printf("3. 查找学生\n"); + printf("4. 打印学生列表\n"); + printf("5. 清空学生列表\n"); + printf("6. 退出\n"); + printf("请选择操作(1-6): "); + scanf("%d", &choice); + + switch (choice) { + case 1: { + // 添加学生 + Student newStudent; + printf("请输入学号(1-100): "); + scanf("%d", &newStudent.id); + printf("请输入姓名(不超过4个字符): "); + scanf("%s", newStudent.name); + + insertStudent(&studentList, newStudent); + break; + } + case 2: { + // 删除学生 + int id; + printf("请输入要删除学生的学号: "); + scanf("%d", &id); + + deleteStudentById(&studentList, id); + break; + } + case 3: { + // 查找学生 + int id; + printf("请输入要查找学生的学号: "); + scanf("%d", &id); + + Node *foundStudent = findStudentById(studentList, id); + if (foundStudent != NULL) { + printf("找到学生:学号 %d,姓名 %s\n", foundStudent->student.id, foundStudent->student.name); + } + else { + printf("未找到学生。\n"); + } + break; + } + case 4: + // 打印学生列表 + printList(studentList); + break; + case 5: + // 清空学生列表 + clearList(&studentList); + printf("学生列表已清空。\n"); + break; + case 6: + // 退出程序 + printf("程序已退出。\n"); + break; + default: + printf("无效的选择,请重新输入。\n"); + } + } while (choice != 6); + + return 0; +} + +// 初始化链表 +void initList(LinkedList *list) { + list->head = NULL; +} + +// 在有序链表中插入学生 +void insertStudent(LinkedList *list, Student student) { + Node *newNode = (Node *)malloc(sizeof(Node)); + newNode->student = student; + newNode->next = NULL; + + if (list->head == NULL || student.id < list->head->student.id) { + // 插入头部 + newNode->next = list->head; + list->head = newNode; + } + else { + // 插入中间或尾部 + Node *current = list->head; + while (current->next != NULL && student.id > current->next->student.id) { + current = current->next; + } + newNode->next = current->next; + current->next = newNode; + } + + printf("学生已添加:学号 %d,姓名 %s\n", student.id, student.name); +} + +// 打印学生列表 +void printList(LinkedList list) { + Node *current = list.head; + printf("\n学生列表:\n"); + while (current != NULL) { + printf("学号 %d,姓名 %s\n", current->student.id, current->student.name); + current = current->next; + } +} + +// 根据学号查找学生 +Node *findStudentById(LinkedList list, int id) { + Node *current = list.head; + while (current != NULL) { + if (current->student.id == id) { + return current; + } + current = current->next; + } + return NULL; +} + +// 根据学号删除学生 +void deleteStudentById(LinkedList *list, int id) { + Node *current = list->head; + Node *prev = NULL; + + while (current != NULL && current->student.id != id) { + prev = current; + current = current->next; + } + + if (current != NULL) { + // 找到学生,进行删除操作 + if (prev == NULL) { + // 删除头节点 + list->head = current->next; + } + else { + prev->next = current->next; + } + free(current); + printf("学生已删除:学号 %d\n", id); + } + else { + printf("未找到学生。\n"); + } +} + +// 清空学生列表 +void clearList(LinkedList *list) { + Node *current = list->head; + while (current != NULL) { + Node *next = current->next; + free(current); + current = next; + } + list->head = NULL; +} diff --git a/Practical-Teaching/Data-Sructure/Big/2/2.1.cpp b/Practical-Teaching/Data-Sructure/Big/2/2.1.cpp new file mode 100644 index 0000000..c150b6e --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/2/2.1.cpp @@ -0,0 +1,106 @@ +#include +#include + +using namespace std; + +struct TreeNode { + char data; + TreeNode *left; + TreeNode *right; +}; + +// 创建二叉树 +TreeNode *create() { + char ch; + cin >> ch; + if (ch == '#') + return nullptr; + TreeNode *node = new TreeNode(); + node->data = ch; + node->left = create(); + node->right = create(); + return node; +} + +// 销毁二叉树 +void destroy(TreeNode *root) { + if (root == nullptr) + return; + destroy(root->left); + destroy(root->right); + delete root; +} + +// 先序遍历 +void preOrder(TreeNode *root) { + if (root == nullptr) + return; + cout << root->data << ' '; + preOrder(root->left); + preOrder(root->right); +} + +// 中序遍历 +void inOrder(TreeNode *root) { + if (root == nullptr) + return; + inOrder(root->left); + cout << root->data << ' '; + inOrder(root->right); +} + +// 后序遍历 +void postOrder(TreeNode *root) { + if (root == nullptr) + return; + postOrder(root->left); + postOrder(root->right); + cout << root->data << ' '; +} + +// 层次遍历 +void levelOrder(TreeNode *root) { + if (root == nullptr) + return; + queue q; + q.push(root); + while (!q.empty()) { + TreeNode *node = q.front(); + q.pop(); + cout << node->data << ' '; + if (node->left) + q.push(node->left); + if (node->right) + q.push(node->right); + } +} + +// 用括号表示法输出二叉树 +void printWithBrackets(TreeNode *root) { + if (root == nullptr) + return; + cout << root->data; + if (root->left || root->right) { + cout << '('; + printWithBrackets(root->left); + cout << ','; + printWithBrackets(root->right); + cout << ')'; + } +} + +int main() { + TreeNode *root = create(); + preOrder(root); + cout << endl; + inOrder(root); + cout << endl; + postOrder(root); + cout << endl; + levelOrder(root); + cout << endl; + printWithBrackets(root); + cout << endl; + destroy(root); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/2/2.2.cpp b/Practical-Teaching/Data-Sructure/Big/2/2.2.cpp new file mode 100644 index 0000000..3746e9c --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/2/2.2.cpp @@ -0,0 +1,80 @@ +#include + +using namespace std; + +// 定义线索二叉树节点 +struct Node { + int data; + Node *left, *right; + int ltag, rtag; // 左右标志位,0表示指向子节点,1表示指向前驱或后继 +}; + +Node *pre = NULL; // 全局变量,记录上一个访问的节点 + +// 创建线索二叉树 +Node *createTree(int data) { + Node *node = new Node(); + node->data = data; + node->left = node->right = NULL; + node->ltag = node->rtag = 0; + return node; +} + +// 中序遍历线索化 +void inThreading(Node *node) { + if (node) { + inThreading(node->left); // 递归左子树 + if (!node->left) { // 如果该节点没有左孩子,设置ltag为1,并让left指向上一个节点 + node->ltag = 1; + node->left = pre; + } + if (pre && !pre->right) { // 如果上一个节点没有右孩子,设置rtag为1,并让right指向当前节点 + pre->rtag = 1; + pre->right = node; + } + pre = node; + inThreading(node->right); // 递归右子树 + } +} + +// 中序遍历线索二叉树 +void inOrder(Node *node) { + while (node) { + while (!node->ltag) // 如果ltag为0,一直找到最左下节点 + node = node->left; + cout << node->data << " "; + while (node->rtag) { // 如果rtag为1,一直找到最右下节点 + node = node->right; + cout << node->data << " "; + } + node = node->right; // 转向右子树 + } +} + +// 查找节点的前驱 +Node *findPredecessor(Node *node) { + if (node->ltag) // 如果ltag为1,left指向的就是前驱 + return node->left; + else + return NULL; +} + +// 查找节点的后继 +Node *findSuccessor(Node *node) { + if (node->rtag) // 如果rtag为1,right指向的就是后继 + return node->right; + else + return NULL; +} + +// 主函数 +int main() { + Node *root = createTree(1); + root->left = createTree(2); + root->right = createTree(3); + root->left->left = createTree(4); + root->left->right = createTree(5); + inThreading(root); + inOrder(root); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/2/2.3.cpp b/Practical-Teaching/Data-Sructure/Big/2/2.3.cpp new file mode 100644 index 0000000..517440e --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/2/2.3.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using namespace std; + +struct Node { + int weight; + string code; + Node *left, *right; + Node(int w) : weight(w), left(NULL), right(NULL) {} +}; + +struct cmp { + bool operator()(Node *a, Node *b) { + return a->weight > b->weight; + } +}; + +void generateHuffmanCode(Node *root, string str) { + if (!root) + return; + if (!root->left && !root->right) { + root->code = str; + } + generateHuffmanCode(root->left, str + "0"); + generateHuffmanCode(root->right, str + "1"); +} + +int main() { + int n; + cin >> n; + priority_queue, cmp> pq; + for (int i = 0; i < n; ++i) { + int w; + cin >> w; + pq.push(new Node(w)); + } + while (pq.size() != 1) { + Node *left = pq.top(); + pq.pop(); + Node *right = pq.top(); + pq.pop(); + Node *parent = new Node(left->weight + right->weight); + parent->left = left; + parent->right = right; + pq.push(parent); + } + generateHuffmanCode(pq.top(), ""); + vector nodes; + nodes.push_back(pq.top()); + while (!nodes.empty()) { + Node *node = nodes.back(); + nodes.pop_back(); + if (node->left) + nodes.push_back(node->left); + if (node->right) + nodes.push_back(node->right); + if (!node->left && !node->right) { + cout << node->code << " "; + } + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/2/2.4.cpp b/Practical-Teaching/Data-Sructure/Big/2/2.4.cpp new file mode 100644 index 0000000..fa977c5 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/2/2.4.cpp @@ -0,0 +1,59 @@ +#include +#include + +using namespace std; + +class Node { +public: + string name; + map children; + + Node(string name) : name(name) {} + + Node *find(string path) { + if (path.empty()) + return this; + int pos = path.find('/'); + string first = pos == string::npos ? path : path.substr(0, pos); + string rest = pos == string::npos ? "" : path.substr(pos + 1); + if (children.count(first) == 0) + return nullptr; + return children[first]->find(rest); + } + + void add(string path) { + int pos = path.find('/'); + string first = pos == string::npos ? path : path.substr(0, pos); + string rest = pos == string::npos ? "" : path.substr(pos + 1); + if (children.count(first) == 0) + children[first] = new Node(first); + if (!rest.empty()) + children[first]->add(rest); + } + + bool remove(string path) { + int pos = path.find('/'); + string first = pos == string::npos ? path : path.substr(0, pos); + string rest = pos == string::npos ? "" : path.substr(pos + 1); + if (children.count(first) == 0) + return false; + if (rest.empty()) { + delete children[first]; + children.erase(first); + return true; + } + return children[first]->remove(rest); + } +}; + +int main() { + Node root("/"); + root.add("dir1/dir2/file"); + cout << (root.find("dir1/dir2/file") != nullptr) << endl; + cout << (root.find("dir1/dir2") != nullptr) << endl; + cout << (root.find("dir1") != nullptr) << endl; + cout << (root.find("dir1/dir3") == nullptr) << endl; + root.remove("dir1/dir2/file"); + cout << (root.find("dir1/dir2/file") == nullptr) << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/3/3.1.cpp b/Practical-Teaching/Data-Sructure/Big/3/3.1.cpp new file mode 100644 index 0000000..7493b53 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/3/3.1.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +using namespace std; + +// 图的邻接矩阵存储 +vector> adjMatrix; + +// 图的邻接表存储 +vector> adjList; + +// 图的深度优先遍历 +void DFS(int start, vector &visited) { + stack s; + s.push(start); + visited[start] = true; + while (!s.empty()) { + int vertex = s.top(); + s.pop(); + cout << vertex << " "; + for (int i = 0; i < adjList[vertex].size(); i++) { + if (!visited[adjList[vertex][i]]) { + s.push(adjList[vertex][i]); + visited[adjList[vertex][i]] = true; + } + } + } +} + +// 图的广度优先遍历 +void BFS(int start, vector &visited) { + queue q; + q.push(start); + visited[start] = true; + while (!q.empty()) { + int vertex = q.front(); + q.pop(); + cout << vertex << " "; + for (int i = 0; i < adjList[vertex].size(); i++) { + if (!visited[adjList[vertex][i]]) { + q.push(adjList[vertex][i]); + visited[adjList[vertex][i]] = true; + } + } + } +} + +int main() { + int n, m; + cin >> n >> m; // 输入顶点数和边数 + adjMatrix.resize(n, vector(n, 0)); + adjList.resize(n); + for (int i = 0; i < m; i++) { + int u, v; + cin >> u >> v; // 输入边的两个顶点 + adjMatrix[u][v] = 1; + adjMatrix[v][u] = 1; + adjList[u].push_back(v); + adjList[v].push_back(u); + } + vector visited(n, false); + DFS(0, visited); // 从顶点0开始深度优先遍历 + cout << endl; + fill(visited.begin(), visited.end(), false); + BFS(0, visited); // 从顶点0开始广度优先遍历 + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/3/3.2.cpp b/Practical-Teaching/Data-Sructure/Big/3/3.2.cpp new file mode 100644 index 0000000..9e8e3a7 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/3/3.2.cpp @@ -0,0 +1,92 @@ +#include +#include +#include + +using namespace std; + +const int MAX = 1e9; +const int N = 6; +double graph[N][N] = { + { 0, 0.6, 0.1, 0.5, 0, 0 }, + { 0.6, 0, 0.5, 0, 0.3, 0 }, + { 0.1, 0.5, 0, 0.5, 0.6, 0.4 }, + { 0.5, 0, 0.5, 0, 0, 0.2 }, + { 0, 0.3, 0.6, 0, 0, 0.6 }, + { 0, 0, 0.4, 0.2, 0.6, 0 } +}; + +// Prim's Algorithm +void prim() { + vector selected(N, false); + vector minWeight(N, MAX); + minWeight[0] = 0; + for (int i = 0; i < N; ++i) { + int u = -1; + for (int j = 0; j < N; ++j) { + if (!selected[j] && (u == -1 || minWeight[j] < minWeight[u])) { + u = j; + } + } + selected[u] = true; + for (int v = 0; v < N; ++v) { + if (!selected[v] && graph[u][v] != 0 && graph[u][v] < minWeight[v]) { + minWeight[v] = graph[u][v]; + } + } + } + double totalWeight = 0; + for (int i = 0; i < N; ++i) { + totalWeight += minWeight[i]; + } + cout << "Minimum cost with Prim's Algorithm: " << totalWeight << endl; +} + +// Kruskal's Algorithm +struct Edge { + int u, v; + double weight; + bool operator<(const Edge &other) const { + return weight < other.weight; + } +}; + +int parent[N]; +int find(int x) { + if (x != parent[x]) { + parent[x] = find(parent[x]); + } + return parent[x]; +} + +void unionSet(int x, int y) { + parent[find(x)] = find(y); +} + +void kruskal() { + vector edges; + for (int i = 0; i < N; ++i) { + for (int j = i + 1; j < N; ++j) { + if (graph[i][j] > 0) { + edges.push_back({ i, j, graph[i][j] }); + } + } + } + sort(edges.begin(), edges.end()); + for (int i = 0; i < N; ++i) { + parent[i] = i; + } + double totalWeight = 0; + for (const Edge &edge : edges) { + if (find(edge.u) != find(edge.v)) { + totalWeight += edge.weight; + unionSet(edge.u, edge.v); + } + } + cout << "Minimum cost with Kruskal's Algorithm: " << totalWeight << endl; +} + +int main() { + prim(); + kruskal(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/3/3.3.cpp b/Practical-Teaching/Data-Sructure/Big/3/3.3.cpp new file mode 100644 index 0000000..08d9acb --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/3/3.3.cpp @@ -0,0 +1,139 @@ +#include +#include +#include + +using namespace std; + +// 定义课程结构体,包含课程号,学分,入度,邻接表 +struct Course { + string id; // 课程号 + int credit; // 学分 + int indegree; // 入度 + vector adj; // 邻接表 + Course(string i, int c) : id(i), credit(c), indegree(0) {} // 构造函数 +}; + +// 定义拓扑排序函数,参数为课程数组,学期总数,每学期学分上限,课程总数 +void topologicalSort(vector &courses, int term, int limit, int num) { + queue q; // 定义一个队列,用于存放入度为0的课程 + vector result; // 定义一个数组,用于存放拓扑排序的结果 + int count = 0; // 定义一个计数器,用于记录已经安排的课程数 + // 遍历课程数组,将入度为0的课程入队,并输出 + for (int i = 0; i < num; i++) { + if (courses[i].indegree == 0) + q.push(i); + } + // 当队列不为空时,循环执行以下操作 + while (!q.empty()) { + int u = q.front(); // 取出队首元素 + q.pop(); // 出队 + result.push_back(u); // 将队首元素加入结果数组 + count++; // 计数器加一 + // 遍历队首元素的邻接表,将其邻接课程的入度减一,如果入度变为0,则入队 + for (int v : courses[u].adj) { + courses[v].indegree--; + if (courses[v].indegree == 0) { + q.push(v); + } + } + } + // 如果计数器等于课程总数,说明拓扑排序成功,否则说明有环,无法完成所有课程 + if (count == num) { + cout << "拓扑排序成功,结果为:" << endl; + // 输出拓扑排序结果 + for (int i = 0; i < num; i++) { + cout << courses[result[i]].id << " "; + } + cout << endl; + // 定义一个二维数组,用于存放每个学期的课程安排 + vector> plan(term); + // 定义一个变量,用于记录当前安排到哪个学期 + int current = 0; + // 定义一个变量,用于记录当前学期的已安排学分 + int credit = 0; + // 遍历拓扑排序结果,按照策略安排课程 + for (int i = 0; i < num; i++) { + // 如果当前课程的学分加上已安排学分超过学分上限,或者当前学期已满,则安排到下一个学期 + if (credit + courses[result[i]].credit > limit || plan[current].size() == term) { + current++; + credit = 0; + } + // 如果当前学期还有空余,且没有超过学分上限,则安排当前课程到当前学期 + if (current < term && credit + courses[result[i]].credit <= limit) { + plan[current].push_back(result[i]); + credit += courses[result[i]].credit; + } + } + // 输出每个学期的课程安排 + cout << "按照给定的条件,最少需要" << current + 1 << "个学期完成所有课程,具体安排如下:" << endl; + for (int i = 0; i <= current; i++) { + cout << "第" << i + 1 << "个学期的课程有:"; + for (int j = 0; j < plan[i].size(); j++) { + cout << courses[plan[i][j]].id << " "; + } + cout << endl; + } + } + else { + cout << "拓扑排序失败,无法完成所有课程的学习" << endl; + } +} + +// 定义主函数,用于测试代码的功能 +int main() { + // 定义课程总数,学期总数,每学期学分上限 + int num, term, limit; + // 从标准输入读取这些参数 + cout << "请输入学期总数,每学期学分上限,课程总数,用空格隔开:" << endl; + cin >> term >> limit >> num; + // 定义一个课程数组,用于存放课程信息 + vector courses; + // 初始化课程信息,根据题目给定的数据 + courses.push_back(Course("C1", 2)); + courses.push_back(Course("C2", 3)); + courses.push_back(Course("C3", 4)); + courses.push_back(Course("C4", 3)); + courses.push_back(Course("C5", 2)); + courses.push_back(Course("C6", 3)); + courses.push_back(Course("C7", 4)); + courses.push_back(Course("C8", 4)); + courses.push_back(Course("C9", 5)); + courses.push_back(Course("C10", 3)); + courses.push_back(Course("C11", 2)); + courses.push_back(Course("C12", 5)); + courses.push_back(Course("C13", 3)); + courses.push_back(Course("C14", 3)); + // 初始化课程之间的先修关系,根据题目给定的数据 + courses[0].adj.push_back(1); // C1 -> C2 + courses[0].adj.push_back(2); // C1 -> C3 + courses[0].adj.push_back(3); // C1 -> C4 + courses[0].adj.push_back(11); // C1 -> C12 + courses[0].adj.push_back(13); // C1 -> C14 + courses[1].adj.push_back(2); // C2 -> C3 + courses[2].adj.push_back(4); // C3 -> C5 + courses[2].adj.push_back(6); // C3 -> C7 + courses[2].adj.push_back(7); // C3 -> C8 + courses[3].adj.push_back(4); // C4 -> C5 + courses[3].adj.push_back(12); // C4 -> C13 + courses[4].adj.push_back(6); // C5 -> C7 + courses[5].adj.push_back(7); // C6 -> C8 + courses[5].adj.push_back(12); // C6 -> C13 + courses[5].adj.push_back(13); // C6 -> C14 + courses[8].adj.push_back(5); // C9 -> C6 + courses[8].adj.push_back(9); // C9 -> C10 + courses[8].adj.push_back(10); // C9 -> C11 + courses[8].adj.push_back(11); // C9 -> C12 + courses[9].adj.push_back(11); // C10 -> C12 + courses[10].adj.push_back(5); // C11 -> C6 + courses[10].adj.push_back(13); // C11 -> C14 + courses[12].adj.push_back(13); // C13 -> C14 + // 更新每个课程的入度 + for (int i = 0; i < num; i++) { + for (int j : courses[i].adj) { + courses[j].indegree++; + } + } + // 调用拓扑排序函数,输出结果 + topologicalSort(courses, term, limit, num); + return 0; +} diff --git a/Practical-Teaching/Data-Sructure/Big/3/3.4.cpp b/Practical-Teaching/Data-Sructure/Big/3/3.4.cpp new file mode 100644 index 0000000..cf6656a --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/3/3.4.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using namespace std; + +#define INF INT_MAX +#define N 6 + +void Dijkstra(int graph[N][N], int start) { + vector dist(N, INF); + dist[start] = 0; + vector visited(N, false); + vector prev(N, -1); + + for (int count = 0; count < N - 1; count++) { + int min = INF, min_index; + for (int v = 0; v < N; v++) + if (!visited[v] && dist[v] <= min) + min = dist[v], min_index = v; + + int u = min_index; + visited[u] = true; + + for (int v = 0; v < N; v++) + if (!visited[v] && graph[u][v] && dist[u] != INF && dist[u] + graph[u][v] < dist[v]) { + dist[v] = dist[u] + graph[u][v]; + prev[v] = u; + } + } + + for (int i = 0; i < N; i++) { + if (i != start) { + cout << "Path from " << start << " to " << i << ": "; + if (dist[i] == INF) { + cout << "No path\n"; + } + else { + vector path; + for (int j = i; j != -1; j = prev[j]) + path.push_back(j); + for (int j = path.size() - 1; j > 0; j--) + cout << path[j] << " -> "; + cout << path[0] << " (Cost: " << dist[i] << ")\n"; + } + } + } +} + +int main() { + int graph[N][N] = { + { 0, 0, 10, 0, 30, 100 }, + { 0, 0, 5, 0, 0, 0 }, + { 0, 0, 0, 50, 0, 0 }, + { 0, 0, 0, 0, 0, 10 }, + { 0, 0, 0, 20, 0, 60 }, + { 0, 0, 0, 0, 0, 0 } + }; + + for (int i = 0; i < N; i++) + Dijkstra(graph, i); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/4/4.1.cpp b/Practical-Teaching/Data-Sructure/Big/4/4.1.cpp new file mode 100644 index 0000000..80e1c6a --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/4/4.1.cpp @@ -0,0 +1,109 @@ +#include +#include + +using namespace std; + +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} +}; + +// 插入节点 +TreeNode *insertNode(TreeNode *root, int val) { + if (root == NULL) { + return new TreeNode(val); + } + if (val < root->val) { + root->left = insertNode(root->left, val); + } + else if (val > root->val) { + root->right = insertNode(root->right, val); + } + return root; +} + +// 删除节点 +TreeNode *deleteNode(TreeNode *root, int key) { + if (root == NULL) + return root; + if (key < root->val) { + root->left = deleteNode(root->left, key); + } + else if (key > root->val) { + root->right = deleteNode(root->right, key); + } + else { + if (root->left == NULL) { + TreeNode *temp = root->right; + delete root; + return temp; + } + else if (root->right == NULL) { + TreeNode *temp = root->left; + delete root; + return temp; + } + TreeNode *temp = root->right; + while (temp && temp->left != NULL) + temp = temp->left; + root->val = temp->val; + root->right = deleteNode(root->right, temp->val); + } + return root; +} + +// 判断是否为二叉搜索树 +bool isValidBST(TreeNode *root, TreeNode *minNode = NULL, TreeNode *maxNode = NULL) { + if (root == NULL) + return true; + if (minNode != NULL && root->val <= minNode->val || maxNode != NULL && root->val >= maxNode->val) { + return false; + } + return isValidBST(root->left, minNode, root) && isValidBST(root->right, root, maxNode); +} + +// 查找最大值和第二大值 +pair findMaxAndSecondMax(TreeNode *root) { + int maxVal = numeric_limits::min(); + int secondMaxVal = numeric_limits::min(); + TreeNode *curr = root; + while (curr) { + if (curr->val > maxVal) { + secondMaxVal = maxVal; + maxVal = curr->val; + } + else if (curr->val > secondMaxVal && curr->val < maxVal) { + secondMaxVal = curr->val; + } + curr = curr->right; + } + return { maxVal, secondMaxVal }; +} + +// 主函数,用于测试以上所有功能 +int main() { + int n; + TreeNode *root = NULL; + cout << "Enter a number to insert: "; + while (true) { + int val; + cin >> val; + if (val == -1) + break; + root = insertNode(root, val); + } + + cout << "Is valid BST: " << (isValidBST(root) ? "Yes" : "No") << endl; + + auto maxAndSecondMax = findMaxAndSecondMax(root); + cout << "Max: " << maxAndSecondMax.first << ", Second Max: " << maxAndSecondMax.second << endl; + + cout << "Enter a number to delete: "; + cin >> n; + root = deleteNode(root, n); + cout << "After deleting " << n << ", is valid BST: " << (isValidBST(root) ? "Yes" : "No") << endl; + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Data-Sructure/Big/4/4.2.cpp b/Practical-Teaching/Data-Sructure/Big/4/4.2.cpp new file mode 100644 index 0000000..cf115df --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/4/4.2.cpp @@ -0,0 +1,123 @@ +#include + +using namespace std; + +struct Node { + int key; + Node *left; + Node *right; + int height; +}; + +Node *newNode(int key) { + Node *node = new Node(); + node->key = key; + node->left = NULL; + node->right = NULL; + node->height = 1; + return (node); +} + +int height(Node *N) { + if (N == NULL) + return 0; + return N->height; +} + +int max(int a, int b) { + return (a > b) ? a : b; +} + +Node *rightRotate(Node *y) { + Node *x = y->left; + Node *T2 = x->right; + x->right = y; + y->left = T2; + y->height = max(height(y->left), height(y->right)) + 1; + x->height = max(height(x->left), height(x->right)) + 1; + return x; +} + +Node *leftRotate(Node *x) { + Node *y = x->right; + Node *T2 = y->left; + y->left = x; + x->right = T2; + x->height = max(height(x->left), height(x->right)) + 1; + y->height = max(height(y->left), height(y->right)) + 1; + return y; +} + +int getBalance(Node *N) { + if (N == NULL) + return 0; + return height(N->left) - height(N->right); +} + +Node *insert(Node *node, int key) { + if (node == NULL) + return (newNode(key)); + if (key < node->key) + node->left = insert(node->left, key); + else if (key > node->key) + node->right = insert(node->right, key); + else + return node; + + node->height = 1 + max(height(node->left), height(node->right)); + + int balance = getBalance(node); + + if (balance > 1 && key < node->left->key) + return rightRotate(node); + + if (balance < -1 && key > node->right->key) + return leftRotate(node); + + if (balance > 1 && key > node->left->key) { + node->left = leftRotate(node->left); + return rightRotate(node); + } + + if (balance < -1 && key < node->right->key) { + node->right = rightRotate(node->right); + return leftRotate(node); + } + + return node; +} + +void preOrder(Node *root) { + if (root != NULL) { + cout << root->key << " "; + preOrder(root->left); + preOrder(root->right); + } +} + +bool isBalanced(Node *root) { + int balance = getBalance(root); + if (balance > 1 || balance < -1) + return false; + else + return true; +} + +int main() { + Node *root = NULL; + while (true) { + int val; + cin >> val; + if (val == -1) + break; + root = insert(root, val); + } + if (isBalanced(root)) + cout << "The tree is balanced.\n"; + else + cout << "The tree is not balanced.\n"; + cout << "Preorder traversal of the constructed AVL tree is \n"; + preOrder(root); + + return 0; +} diff --git a/Practical-Teaching/Data-Sructure/Big/4/4.3.cpp b/Practical-Teaching/Data-Sructure/Big/4/4.3.cpp new file mode 100644 index 0000000..175c8f7 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/4/4.3.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +using namespace std; + +const int Base = 31; +const int TableSize = 1000; + +struct Node { + string key; + int value; + Node(string key, int value) : key(key), value(value) {} +}; + +class HashTable { +private: + vector> table; + int hashFunc(string key) { + int hashVal = 0; + for (int i = 0; i < key.length(); i++) { + hashVal = (hashVal + key[i] * static_cast(pow(Base, i))) % TableSize; + } + return hashVal; + } + +public: + HashTable() { + table.resize(TableSize); + } + void insert(string key, int value) { + int hashVal = hashFunc(key); + for (auto &node : table[hashVal]) { + if (node.key == key) { + node.value = value; + return; + } + } + table[hashVal].push_back(Node(key, value)); + } + int search(string key) { + int hashVal = hashFunc(key); + for (auto &node : table[hashVal]) { + if (node.key == key) { + return node.value; + } + } + return -1; + } + void destroy() { + for (auto &bucket : table) { + bucket.clear(); + } + } +}; + +int main() { + HashTable ht; + ht.insert("Alice", 1); + ht.insert("Bob", 2); + cout << "Alice: " << ht.search("Alice") << endl; + cout << "Bob: " << ht.search("Bob") << endl; + cout << "Charlie: " << ht.search("Charlie") << endl; + ht.destroy(); + return 0; +} diff --git a/Practical-Teaching/Data-Sructure/Big/4/4.4.cpp b/Practical-Teaching/Data-Sructure/Big/4/4.4.cpp new file mode 100644 index 0000000..4244991 --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/4/4.4.cpp @@ -0,0 +1,152 @@ +#include +#include + +using namespace std; + +// 选择排序 +void selectionSort(vector &nums) { + int n = nums.size(); + for (int i = 0; i < n; i++) { + int minIndex = i; + for (int j = i + 1; j < n; j++) { + if (nums[j] < nums[minIndex]) { + minIndex = j; + } + } + swap(nums[i], nums[minIndex]); + } +} + +// 插入排序 +void insertionSort(vector &nums) { + int n = nums.size(); + for (int i = 1; i < n; i++) { + int key = nums[i]; + int j = i - 1; + while (j >= 0 && nums[j] > key) { + nums[j + 1] = nums[j]; + j--; + } + nums[j + 1] = key; + } +} + +// 归并排序 +void merge(vector &nums, int left, int mid, int right) { + vector temp(right - left + 1); + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { + temp[k++] = nums[i] <= nums[j] ? nums[i++] : nums[j++]; + } + while (i <= mid) { + temp[k++] = nums[i++]; + } + while (j <= right) { + temp[k++] = nums[j++]; + } + for (int i = left; i <= right; i++) { + nums[i] = temp[i - left]; + } +} + +void mergeSort(vector &nums, int left, int right) { + if (left < right) { + int mid = left + (right - left) / 2; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + merge(nums, left, mid, right); + } +} + +// 单指针快速排序 +int partitionSingle(vector &nums, int left, int right) { + int pivot = nums[right]; + int i = left; + for (int j = left; j < right; j++) { + if (nums[j] < pivot) { + swap(nums[i], nums[j]); + i++; + } + } + swap(nums[i], nums[right]); + return i; +} + +void quickSortSingle(vector &nums, int left, int right) { + if (left < right) { + int pivotIndex = partitionSingle(nums, left, right); + quickSortSingle(nums, left, pivotIndex - 1); + quickSortSingle(nums, pivotIndex + 1, right); + } +} + +// 双指针快速排序 +int partitionDouble(vector &nums, int left, int right) { + int pivot = nums[left]; + while (left < right) { + while (left < right && nums[right] >= pivot) { + right--; + } + nums[left] = nums[right]; + while (left < right && nums[left] <= pivot) { + left++; + } + nums[right] = nums[left]; + } + nums[left] = pivot; + return left; +} + +void quickSortDouble(vector &nums, int left, int right) { + if (left < right) { + int pivotIndex = partitionDouble(nums, left, right); + quickSortDouble(nums, left, pivotIndex - 1); + quickSortDouble(nums, pivotIndex + 1, right); + } +} + +// 主函数,用于测试上述排序算法 +int main() { + vector arr; + int n; + cout << "请输入你想要排序的数字的数量:"; + cin >> n; + cout << "请输入这些数字(用空格隔开):"; + for (int i = 0; i < n; i++) { + int num; + cin >> num; + arr.push_back(num); + } + + selectionSort(arr); + cout << "选择排序后的数组:"; + for (int i = 0; i < arr.size(); i++) + cout << arr[i] << " "; + cout << "\n"; + + insertionSort(arr); + cout << "插入排序后的数组:"; + for (int i = 0; i < arr.size(); i++) + cout << arr[i] << " "; + cout << "\n"; + + mergeSort(arr, 0, arr.size() - 1); + cout << "归并排序后的数组:"; + for (int i = 0; i < arr.size(); i++) + cout << arr[i] << " "; + cout << "\n"; + + quickSortSingle(arr, 0, arr.size() - 1); + cout << "单指针快速排序后的数组:"; + for (int i = 0; i < arr.size(); i++) + cout << arr[i] << " "; + cout << "\n"; + + quickSortDouble(arr, 0, arr.size() - 1); + cout << "双指针快速排序后的数组:"; + for (int i = 0; i < arr.size(); i++) + cout << arr[i] << " "; + cout << "\n"; + + return 0; +} diff --git a/Practical-Teaching/Data-Sructure/Big/4/4.5.cpp b/Practical-Teaching/Data-Sructure/Big/4/4.5.cpp new file mode 100644 index 0000000..b70069e --- /dev/null +++ b/Practical-Teaching/Data-Sructure/Big/4/4.5.cpp @@ -0,0 +1,83 @@ +#include +#include +#include + +using namespace std; + +// 输入数组元素的函数 +vector inputArray(int n) { + vector arr; + int temp; + + cout << "请输入数组的元素:"; + for (int i = 0; i < n; i++) { + cin >> temp; + arr.push_back(temp); + } + + return arr; +} + +// 方案一:使用优先队列 +void heapSortUsingPriorityQueue(vector &arr) { + priority_queue, greater> pq(arr.begin(), arr.end()); + + int i = 0; + while (!pq.empty()) { + arr[i++] = pq.top(); + pq.pop(); + } +} + +// 方案二:使用向下过滤函数 +void heapify(vector &arr, int n, int i) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n && arr[left] > arr[largest]) + largest = left; + + if (right < n && arr[right] > arr[largest]) + largest = right; + + if (largest != i) { + swap(arr[i], arr[largest]); + heapify(arr, n, largest); + } +} + +void heapSort(vector &arr) { + int n = arr.size(); + + for (int i = n / 2 - 1; i >= 0; i--) + heapify(arr, n, i); + + for (int i = n - 1; i >= 0; i--) { + swap(arr[0], arr[i]); + heapify(arr, i, 0); + } +} + +void printArray(vector &arr) { + for (int i = 0; i < arr.size(); ++i) + cout << arr[i] << " "; + cout << "\n"; +} + +int main() { + int n; + + cout << "请输入数组的元素个数:"; + cin >> n; + + vector arr = inputArray(n); + heapSortUsingPriorityQueue(arr); + cout << "Sorted array using priority queue is \n"; + printArray(arr); + + arr = inputArray(n); + heapSort(arr); + cout << "Sorted array using heapify is \n"; + printArray(arr); +} diff --git a/Practical-Teaching/OPP-in-C++/1/1-1.cpp b/Practical-Teaching/OPP-in-C++/1/1-1.cpp new file mode 100644 index 0000000..a83df00 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/1/1-1.cpp @@ -0,0 +1,19 @@ +// 输入若干数据,找出最大值输出。(从键盘和文件读取两种方式) + +#include + +using namespace std; + +int main() { + double max; + cin >> max; + + double i; + while (cin >> i) + if (i > max) + max = i; + + cout << max << endl; + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/1/1-2.cpp b/Practical-Teaching/OPP-in-C++/1/1-2.cpp new file mode 100644 index 0000000..b42ee9d --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/1/1-2.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +int main() { + ifstream in("input.txt"); + if (!in) { + cout << "Error opening file"; + exit(1); + } + ofstream out("output.txt"); + + double max; + in >> max; + + double i; + while (in >> i) + if (i > max) + max = i; + + out << max << endl; + + in.close(); + out.close(); + + return 0; +} diff --git a/Practical-Teaching/OPP-in-C++/1/2.cpp b/Practical-Teaching/OPP-in-C++/1/2.cpp new file mode 100644 index 0000000..6081f43 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/1/2.cpp @@ -0,0 +1,26 @@ +// day(0~6)代表每月第一天起始位置,stop代表每月天数,每天之间空两个空格。输入不同的day和stop,输出每月日历的样子。 + +#include + +using namespace std; + +int main() { + int day, stop; + cin >> day >> stop; + + cout << " Sun Mon Tue Wed Thu Fri Sat" << endl; + + int t = day; + while (t--) { + cout << " "; + } + + for (int i = 1; i <= stop; i++) { + cout << setw(5) << i; + if ((i + day) % 7 == 0) { + cout << endl; + } + } + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/10/1.cpp b/Practical-Teaching/OPP-in-C++/10/1.cpp new file mode 100644 index 0000000..ba4430a --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/10/1.cpp @@ -0,0 +1,108 @@ +// 实现 Set 模板类,并重载 +、<< 和 >> 操作符 + +#include + +using namespace std; + +template +class Set { +private: + vector a; + +public: + int search(const T &) const; + int operator()(const T &); + int del(const T &); + Set operator*(const Set &) const; + Set operator+(const Set &) const; + Set operator-(const Set &) const; + template + friend ostream &operator<<(ostream &output, const Set &s); + template + friend istream &operator>>(istream &input, Set &s); +}; + +template +int Set::search(const T &x) const { + for (int i = 0; i < a.size(); i++) + if (a[i] == x) + return i; + return -1; +} + +template +int Set::operator()(const T &x) { + if (search(x) != -1) + return 0; + a.push_back(x); + return 1; +} + +template +int Set::del(const T &x) { + int i = search(x); + if (i == -1) + return 0; + a.erase(a.begin() + i); + return 1; +} + +template +Set Set::operator*(const Set &s) const { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) != -1) + t(a[i]); + return t; +} + +template +Set Set::operator+(const Set &s) const { + Set t = *this; + for (int i = 0; i < s.a.size(); i++) + t(s.a[i]); + return t; +} + +template +Set Set::operator-(const Set &s) const { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) == -1) + t(a[i]); + return t; +} + +template +ostream &operator<<(ostream &output, const Set &s) { + for (int i = 0; i < s.a.size(); i++) + output << s.a[i] << ' '; + return output; +} + +template +istream &operator>>(istream &input, Set &s) { + s.a.clear(); + int x; + while (input >> x) + s(x); + return input; +} + +int main() { + Set s1, s2; + cout << "s1: "; + cin >> s1; + s2(9); + s2(10); + s2(11); + s2(12); + s2(13); + s2(14); + s2(15); + cout << "s2: " << s2 << endl; + cout << "s1 * s2: " << s1 * s2 << endl; + cout << "s1 + s2: " << s1 + s2 << endl; + cout << "s1 - s2: " << s1 - s2 << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/10/2.cpp b/Practical-Teaching/OPP-in-C++/10/2.cpp new file mode 100644 index 0000000..b9f9f89 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/10/2.cpp @@ -0,0 +1,41 @@ +// 设计实现一个函数模板,实现任意数据类型的查找 + +#include + +using namespace std; + +template +int find(const T *a, const int &n, const T &x) { + for (int i = 0; i < n; i++) + if (a[i] == x) + return i; + return -1; +} + +int find(const string &s, const char &x) { + for (int i = 0; i < s.length(); i++) + if (s[i] == x) + return i; + return -1; +} + +template +int find(const vector &v, const T &x) { + for (int i = 0; i < v.size(); i++) + if (v[i] == x) + return i; + return -1; +} + +int main() { + int i[5] = { 1, 2, 3, 4, 5 }; + double f[5] = { 1.4, 2.4, 3.4, 4.4, 5.4 }; + string s = "Hello, world!\n"; + vector vi = { 6, 7, 8, 9, 0 }; + vector vd = { 435.6, 57.65, 57.5, 64.5 }; + cout << find(i, 5, 1) << ' ' << find(i, 5, 6) << endl + << find(f, 5, 2.4) << ' ' << find(f, 5, 7.5) << endl + << find(s, '\n') << ' ' << find(s, 'a') << endl + << find(vi, 9) << ' ' << find(vi, 1) << endl + << find(vd, 57.5) << ' ' << find(vd, 5.2) << endl; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/11/1.cpp b/Practical-Teaching/OPP-in-C++/11/1.cpp new file mode 100644 index 0000000..c2b1e00 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/11/1.cpp @@ -0,0 +1,133 @@ +// 实现电话簿管理程序, Mytel类描述单个电话号码,TelManager类负责管理电话号码。把增、删、改、查功能封装到该类中。要求电话号码能从磁盘读写。 + +#include + +using namespace std; + +class Mytel { +public: + void getdata() { cin >> name >> telno; } + void setname(char a[]) { strcpy(name, a); } + void settelno(char a[]) { strcpy(telno, a); } + void putdata() { cout << name << setw(12) << telno << endl; } + string getname() { return name; } + string gettelno() { return telno; } + +private: + char name[12]; + char telno[12]; +}; + +class TelManager { +private: + vector a; + +public: + void loadfile() { + ifstream input("phone.txt"); + if (!input) { + cout << "File cannot be opened." << endl; + return; + } + Mytel s; + char name[12], telno[12]; + input >> name >> telno; + s.setname(name); + s.settelno(telno); + while (input) { + a.push_back(s); + input >> name >> telno; + s.setname(name); + s.settelno(telno); + }; + input.close(); + } + void display() { + cout << "姓名" << setw(8) << "电话" << endl; + for (int i = 0; i < a.size(); i++) + cout << a[i].getname() << setw(12) << a[i].gettelno() << endl; + } + void search() { + string sname; + cout << "输入要查询的姓名(可只输入姓氏):"; + cin >> sname; + cout << "输出查询结果:" << endl; + cout << "姓名" << setw(8) << "电话" << endl; + for (int i = 0; i < a.size(); i++) + if (a[i].getname() == sname) + a[i].putdata(); + } + void add() { + Mytel one; + cout << "姓名" << setw(8) << "电话" << endl; + one.getdata(); + a.push_back(one); + } + void del() { + string dname; + cout << "输入要删除的姓名(可只输入姓氏):"; + cin >> dname; + for (int i = 0; i < a.size(); i++) + if (a[i].getname() == dname) + a.erase(a.begin() + i); + } + void modify() { + string mname; + char mtelno[12]; + cout << "输入要修改的姓名(可只输入姓氏):"; + cin >> mname; + for (int i = 0; i < a.size(); i++) + if (a[i].getname() == mname) { + cout << "电话:"; + cin >> mtelno; + a[i].settelno(mtelno); + } + } + void writefile() { + ofstream file("phone.txt"); + for (int i = 0; i < a.size(); i++) + file << a[i].getname() << "\t" << a[i].gettelno() << endl; + file.close(); + } +}; + +int main() { + int sel; + TelManager m; + while (1) { + cout << "***********************电话薄管理系统***********************"; + cout << endl + << endl; + cout << "1:加载数据 2:输出数据 3:按姓名查询 4:添加数据" << endl + << "5:删除数据 6:修改数据 7.保存数据 0:退出" << endl; + cout << "************************************************************"; + cout << "\n请选择 (0 - 7): "; + cin >> sel; + switch (sel) { + case 1: + m.loadfile(); + break; + case 2: + m.display(); + break; + case 3: + m.search(); + break; + case 4: + m.add(); + break; + case 5: + m.del(); + break; + case 6: + m.modify(); + break; + case 7: + m.writefile(); + break; + case 0: + exit(1); + } + } + return 0; +} diff --git a/Practical-Teaching/OPP-in-C++/12/1.cpp b/Practical-Teaching/OPP-in-C++/12/1.cpp new file mode 100644 index 0000000..0284f7f --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/12/1.cpp @@ -0,0 +1,53 @@ +// 写一个程序,将 24 小时格式时间转换为 12 小时格式。定义一个名为 TimeMistake 的异常类,处理用户输入的非法时间,比如 10:65 或者无效字符。 + +#include + +using namespace std; + +class TimeMistake { + string message; + +public: + TimeMistake(string msg) { message = msg; } + string getMessage() { return message; } +}; + +void test() { + cout << "Please enter a time in 24-hour format (such as 14:30): "; + string input; + cin >> input; + if (input.length() != 5 || input[2] != ':') + throw TimeMistake("Invalid time format"); + else { + int hour = stoi(input.substr(0, 2)); + int min = stoi(input.substr(3, 2)); + if (hour < 0 || hour > 23 || min < 0 || min > 59) + throw TimeMistake("Invalid time value"); + bool am = true; + if (hour > 12) { + am = false; + hour -= 12; + } + if (hour == 0) + hour = 12; + cout << "The converted 12 hour format time is: " << setfill('0') << setw(2) << hour << ':' << setw(2) << min << ' '; + if (am) + cout << "AM"; + else + cout << "PM"; + } +} + +void handler() { + try { + test(); + } + catch (TimeMistake e) { + cerr << "An error occurred: " << e.getMessage() << endl; + } +} + +int main() { + handler(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/2/1.cpp b/Practical-Teaching/OPP-in-C++/2/1.cpp new file mode 100644 index 0000000..e795d29 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/2/1.cpp @@ -0,0 +1,22 @@ +// 设计一个函数print打印字符串,如果只传string型参数s,则字符串长度跟10比较,大于10,打印前10个字符,小于10,全部输出s;如果传string型参数s和int型n,则字符串长度跟n比较,大于n,打印前n个字符,小于n,全部输出s。 + +#include + +using namespace std; + +void print(string s, int n = 10) { + cout << s.substr(0, n) << endl; +} + +int main() { + string s; + int n; + + cin >> s; + print(s); + + cin >> s >> n; + print(s, n); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/2/2.cpp b/Practical-Teaching/OPP-in-C++/2/2.cpp new file mode 100644 index 0000000..25641ec --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/2/2.cpp @@ -0,0 +1,29 @@ +// 输入10个人的名字,按从大到小排序输出。 + +#include + +using namespace std; + +int main() { + vector names; + string input; + + cout << "请输入若干姓名,以空格分隔,按回车结束:" << endl; + + getline(cin, input); + + stringstream ss(input); + string name; + while (ss >> name) + names.push_back(name); + + sort(names.begin(), names.end()); + + cout << "排序后的姓名为:" << endl; + + for (int i = 0; i < names.size(); i++) + cout << names[i] << " "; + cout << endl; + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/2/3.cpp b/Practical-Teaching/OPP-in-C++/2/3.cpp new file mode 100644 index 0000000..a98fb11 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/2/3.cpp @@ -0,0 +1,44 @@ +// 模仿二维数组,使用引用调用和引用返回,把函数代码补完整。 + +#include + +using namespace std; + +struct twodim { + int r; + int c; + float *a; +}; +void get_twodim(twodim &s, int row, int col) { + // 初始化数组 + s.r = row; + s.c = col; + s.a = new float[s.r * s.c]; +} +float &val(twodim &s, int i, int j) { + // 返回i行j列的值 + return s.a[i * s.c + j]; +} +void free_twodim(twodim &s) { + // 释放数组空间 + delete[] s.a; +} +int main() { + struct twodim s; + int i, j; + get_twodim(s, 3, 4); + + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + val(s, i, j) = i + j; + + for (i = 0; i < 3; i++) { + for (j = 0; j < 4; j++) + cout << setw(5) << val(s, i, j); + + cout << endl; + } + free_twodim(s); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/3/1.cpp b/Practical-Teaching/OPP-in-C++/3/1.cpp new file mode 100644 index 0000000..e037f73 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/3/1.cpp @@ -0,0 +1,27 @@ +// 设计一个Circle类,有数据成员radius(半径)、成员函数area(),计算圆的面积。构造一个Circle对象进行测试。 + +#include + +using namespace std; + +class Circle { +private: + double radius; + +public: + void setRadius(double r) { radius = r; } + double area() { return M_PI * radius * radius; } +}; + +int main() { + Circle c; + + double r; + cin >> r; + + c.setRadius(r); + + cout << "Area of circle: " << c.area() << endl; + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/3/2.cpp b/Practical-Teaching/OPP-in-C++/3/2.cpp new file mode 100644 index 0000000..c09e4b6 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/3/2.cpp @@ -0,0 +1,63 @@ +// 字符串序列类的设计:类Sequence的定义 + +#include + +using namespace std; + +class Sequence { +private: + int last; + string s[100]; + +public: + void init(); + void append(string); + void del(string); + void output(); +}; + +void Sequence::init() { + last = -1; +} + +void Sequence::append(string x) { + s[++last] = x; +} + +void Sequence::del(string x) { + for (int i = 0; i <= last; i++) + if (s[i] == x) { + for (int j = i; j < last; j++) + s[j] = s[j + 1]; + + last--; + break; + } +} + +void Sequence::output() { + for (int i = 0; i <= last; i++) + cout << s[i] << ' '; + + cout << '\n'; +} + +int main() { + Sequence seq; + seq.init(); + seq.append("a"); + seq.append("b"); + seq.append("c"); + seq.append("d"); + seq.append("e"); + seq.append("f"); + seq.append("g"); + seq.append("h"); + seq.output(); + seq.del("b"); + seq.del("d"); + seq.del("f"); + seq.del("h"); + seq.output(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/4/1-1.cpp b/Practical-Teaching/OPP-in-C++/4/1-1.cpp new file mode 100644 index 0000000..17615df --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/4/1-1.cpp @@ -0,0 +1,115 @@ +// 设计和实现整型集合类(Set),成员函数要求如下: +// 添加构造函数完成初始化 +// 能添加一个元素,元素不重复 +// 能删除一个元素 +// 输出所有元素 +// 求两个集合对象的交集 +// 求两个集合对象的并集 +// 求两个集合对象的差集 + +// 1_1.cpp + +#include + +using namespace std; + +class Set { +private: + vector a; + +public: + int search(int); + int add(int); + int del(int); + void output(); + Set operator&(Set &); + Set operator|(Set &); + Set operator-(Set &); +}; + +int Set::search(int x) { + for (int i = 0; i < a.size(); i++) + if (a[i] == x) + return i; + return -1; +} + +int Set::add(int x) { + if (search(x) != -1) + return 0; + a.push_back(x); + return 1; +} + +int Set::del(int x) { + int i = search(x); + if (i == -1) + return 0; + a.erase(a.begin() + i); + return 1; +} + +void Set::output() { + for (int i = 0; i < a.size(); i++) { + cout << a[i] << ' '; + } + cout << '\n'; +} + +Set Set::operator&(Set &s) { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) != -1) + t.add(a[i]); + return t; +} + +Set Set::operator|(Set &s) { + Set t = *this; + for (int i = 0; i < s.a.size(); i++) + t.add(s.a[i]); + return t; +} + +Set Set::operator-(Set &s) { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) == -1) + t.add(a[i]); + return t; +} + +int main() { + Set s1, s2; + s1.add(1); + s1.add(2); + s1.add(3); + s1.add(4); + s1.add(5); + s1.add(6); + s1.add(7); + s1.add(8); + s1.add(9); + s1.add(10); + cout << "s1: "; + s1.output(); + s2.add(9); + s2.add(10); + s2.add(11); + s2.add(12); + s2.add(13); + s2.add(14); + s2.add(15); + cout << "s2: "; + s2.output(); + Set s3 = s1 & s2; + cout << "s1 & s2: "; + s3.output(); + Set s4 = s1 | s2; + cout << "s1 | s2: "; + s4.output(); + Set s5 = s1 - s2; + cout << "s1 - s2: "; + s5.output(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/4/1-2.cpp b/Practical-Teaching/OPP-in-C++/4/1-2.cpp new file mode 100644 index 0000000..468cbc1 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/4/1-2.cpp @@ -0,0 +1,118 @@ +// 1_2.cpp + +#include + +using namespace std; + +class Set { +private: + int *a; + int cnt; + int size; + +public: + Set(int = 100); + int search(int); + int add(int); + int del(int); + void output(); + Set intersection(Set &); + Set sum(Set &); + Set difference(Set &); +}; + +Set::Set(int n) { + a = new int[n]; + cnt = 0; + size = n; +} + +int Set::search(int x) { + for (int i = 0; i < cnt; i++) + if (a[i] == x) + return i; + return -1; +} + +int Set::add(int x) { + if (search(x) != -1) + return 0; + if (cnt == size) + return 0; + a[cnt++] = x; + return 1; +} + +int Set::del(int x) { + int i = search(x); + if (i == -1) + return 0; + for (int j = i; j < cnt - 1; j++) + a[j] = a[j + 1]; + cnt--; + return 1; +} + +void Set::output() { + for (int i = 0; i < cnt; i++) + cout << a[i] << " "; + cout << '\n'; +} + +Set Set::intersection(Set &s) { + Set t; + for (int i = 0; i < cnt; i++) + if (s.search(a[i]) != -1) + t.add(a[i]); + return t; +} + +Set Set::sum(Set &s) { + Set t = *this; + for (int i = 0; i < s.cnt; i++) + t.add(s.a[i]); + return t; +} + +Set Set::difference(Set &s) { + Set t; + for (int i = 0; i < cnt; i++) + if (s.search(a[i]) == -1) + t.add(a[i]); + return t; +} + +int main() { + Set s1, s2; + s1.add(1); + s1.add(2); + s1.add(3); + s1.add(4); + s1.add(5); + s1.add(6); + s1.add(7); + s1.add(8); + s1.add(9); + s1.add(10); + cout << "s1: "; + s1.output(); + s2.add(9); + s2.add(10); + s2.add(11); + s2.add(12); + s2.add(13); + s2.add(14); + s2.add(15); + cout << "s2: "; + s2.output(); + Set s3 = s1.intersection(s2); + cout << "s1 & s2: "; + s3.output(); + Set s4 = s1.sum(s2); + cout << "s1 | s2: "; + s4.output(); + Set s5 = s1.difference(s2); + cout << "s1 - s2: "; + s5.output(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/5/1.cpp b/Practical-Teaching/OPP-in-C++/5/1.cpp new file mode 100644 index 0000000..4842b0c --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/5/1.cpp @@ -0,0 +1,59 @@ +// 编程实现Student类,在该类中设计静态数据成员segment1、segment2、segment3、segment4、segment5分别统计分数100-90、89-80,、79-70、69-60、59-0学生人数。设计静态成员函数display()显示各分数段人数。 + +#include + +using namespace std; + +class Student { +private: + static int segment1; + static int segment2; + static int segment3; + static int segment4; + static int segment5; + +public: + Student(int score); + static void display(); +}; + +int Student::segment1 = 0; +int Student::segment2 = 0; +int Student::segment3 = 0; +int Student::segment4 = 0; +int Student::segment5 = 0; + +Student::Student(int score) { + if (score >= 90 && score <= 100) + segment1++; + else if (score >= 80 && score < 90) + segment2++; + else if (score >= 70 && score < 80) + segment3++; + else if (score >= 60 && score < 70) + segment4++; + else if (score >= 0 && score < 60) + segment5++; + else + cout << "Invalid score: " << score << endl; +} + +void Student::display() { + cout << "Segment1: " << segment1 << endl; + cout << "Segment2: " << segment2 << endl; + cout << "Segment3: " << segment3 << endl; + cout << "Segment4: " << segment4 << endl; + cout << "Segment5: " << segment5 << endl; +} + +int main() { + Student s0(115); + Student s1(95); + Student s2(85); + Student s3(75); + Student s4(65); + Student s5(55); + Student s6(45); + Student::display(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/6/1.cpp b/Practical-Teaching/OPP-in-C++/6/1.cpp new file mode 100644 index 0000000..9f49bf4 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/6/1.cpp @@ -0,0 +1,68 @@ +// 设计一个类层次,基类为Date,从Date分别派生出ShortE、MediumDate和LongDate.他们各自有成员函数print(),输出当前日期。 +// Date输出日期格式为:04-14-2018 +// ShortE输出日期格式为:14-04-2018 +// MediumDate输出日期格式为:Apr.14,2018 +// LongDate输出日期格式为:April 14, 2018 + +// class Date +// { +// protected: +// int year, month, day; +// }; + +#include + +using namespace std; + +class Date { +protected: + int year, month, day; + +public: + Date() { + time_t t = time(nullptr); + tm *lt = localtime(&t); + year = lt->tm_year + 1900; + month = lt->tm_mon + 1; + day = lt->tm_mday; + } + void print() { cout << setfill('0') << setw(2) << month << '-' << setw(2) << day << '-' << setw(4) << year << endl; } +}; + +class ShortE : public Date { +public: + ShortE() : Date() {} + void print() { cout << setfill('0') << setw(2) << day << '-' << setw(2) << month << '-' << setw(4) << year << endl; } +}; + +class MediumDate : public Date { +public: + MediumDate() : Date() {} + void print() { + string months[12] = { "Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec." }; + cout << months[month - 1] << day << ',' << year << endl; + } +}; + +class LongDate : public Date { +public: + LongDate() : Date() {} + void print() { + string months[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + cout << months[month - 1] << ' ' << day << ", " << year << endl; + } +}; + +int main() { + Date d; + ShortE s; + MediumDate m; + LongDate l; + + d.print(); + s.print(); + m.print(); + l.print(); + + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/7/1.cpp b/Practical-Teaching/OPP-in-C++/7/1.cpp new file mode 100644 index 0000000..ab0d4cd --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/7/1.cpp @@ -0,0 +1,48 @@ +// Figure 类有一个数据成员radius和虚函数area ()和volume()。从Figure类派生出Sphere类和Column类,分别实现求球体和圆柱体的体积和表面积。并编写测试程序。 + +#include + +const double PI = 3.14; + +using namespace std; + +class Figure { +protected: + double radius; + +public: + virtual double area() const { return 0.0; } + virtual double volume() const { return 0.0; } +}; + +class Sphere : public Figure { +public: + Sphere(double myr) { radius = myr; } + virtual double area() const { return 4 * PI * radius * radius; } + virtual double volume() const { return 4 * PI * radius * radius * radius / 3; } +}; + +class Column : public Figure { +public: + Column(double myr, double myh) { + radius = myr; + height = myh; + } + virtual double area() const { return 2 * PI * radius * height; } + virtual double volume() const { return PI * radius * radius * height; } + +private: + double height; +}; + +void func(Figure &p) { + cout << p.area() << endl; +} + +int main() { + Sphere s(1); + Column c(1, 2); + func(s); + func(c); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/8/1-1.cpp b/Practical-Teaching/OPP-in-C++/8/1-1.cpp new file mode 100644 index 0000000..b2f6ae9 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/8/1-1.cpp @@ -0,0 +1,87 @@ +// 某学校对教师每月工资的计算规定如下:固定工资+课时补贴;教授每课时50元;副教授每课时30元;讲师每课时20元。定义教师抽象类,派生出不同职称的教师类,编写程序求若干个教师的月工资。 +// 职称 等级 每月固定工资(元) +// 教授 一级 8000 +// 二级 7500 +// 副教授 一级 7000 +// 二级 6000 +// 三级 5000 +// 讲师 4500 + +#include + +using namespace std; + +class Teacher { +protected: + double fixed_salary; + double class_hour_subsidy; + +public: + double calculate_salary(int class_hours) { + return fixed_salary + class_hour_subsidy * class_hours; + } +}; + +class Professor : public Teacher { +private: + int level; + +public: + Professor(int l) : level(l) { + switch (level) { + case 1: + fixed_salary = 8000; + break; + case 2: + fixed_salary = 7500; + break; + default: + fixed_salary = 0; + break; + } + class_hour_subsidy = 50; + } +}; + +class AssociateProfessor : public Teacher { +private: + int level; + +public: + AssociateProfessor(int l) : level(l) { + switch (level) { + case 1: + fixed_salary = 7000; + break; + case 2: + fixed_salary = 6000; + break; + case 3: + fixed_salary = 5000; + break; + default: + fixed_salary = 0; + break; + } + class_hour_subsidy = 30; + } +}; + +class Lecturer : public Teacher { +public: + Lecturer() { + fixed_salary = 4500; + class_hour_subsidy = 20; + } +}; + +int main() { + Professor p(1), p2(2); + AssociateProfessor ap(1), ap2(2), ap3(3); + Lecturer l; + Teacher *t[7] = { &p, &p2, &ap, &ap2, &ap3, &l }; + for (int i = 0; i < 6; i++) { + cout << t[i]->calculate_salary(10) << endl; + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/8/1-2.cpp b/Practical-Teaching/OPP-in-C++/8/1-2.cpp new file mode 100644 index 0000000..0182618 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/8/1-2.cpp @@ -0,0 +1,117 @@ +#include + +using namespace std; + +class Teacher { +protected: + int no; + string name; + float salary; + static int totalno; + +public: + Teacher() { + no = totalno++; + cout << "教师姓名:"; + cin >> name; + salary = 0.0; + } + virtual void pay() = 0; + virtual void display() = 0; +}; + +int Teacher::totalno = 10000; + +class Professor : public Teacher { +private: + int level; + float fixed; + float hourlyrate; + int classhours; + +public: + Professor(int l) { + level = l; + fixed = 0.0; + hourlyrate = 50.0; + cout << name << "本月课时:"; + cin >> classhours; + } + void pay() { + if (level == 1) + fixed = 8000.0; + else if (level == 2) + fixed = 7500.0; + salary = fixed + hourlyrate * classhours; + } + void display() { + cout << "教授:" << name << ",编号:" << no << ",本月工资:" << salary << endl; + } +}; + +class AssociateProfessor : public Teacher { +private: + int level; + float fixed; + float hourlyrate; + int classhours; + +public: + AssociateProfessor(int l) { + level = l; + fixed = 0.0; + hourlyrate = 30.0; + cout << name << "本月课时:"; + cin >> classhours; + } + void pay() { + if (level == 1) + fixed = 7000.0; + else if (level == 2) + fixed = 6000.0; + else if (level == 3) + fixed = 5000.0; + salary = fixed + hourlyrate * classhours; + } + void display() { + cout << "副教授:" << name << ",编号:" << no << ",本月工资:" << salary << endl; + } +}; + +class Lecturer : public Teacher { +private: + float fixed; + float hourlyrate; + int classhours; + +public: + Lecturer() { + fixed = 4500.0; + hourlyrate = 20.0; + cout << "本月课时:"; + cin >> classhours; + } + void pay() { + salary = fixed + hourlyrate * classhours; + } + void display() { + cout << "讲师:" << name << ",编号:" << no << ",本月工资:" << salary << endl; + } +}; + +int main() { + Professor p1(1); + Professor p2(2); + AssociateProfessor a1(1); + AssociateProfessor a2(2); + AssociateProfessor a3(3); + Lecturer l; + Teacher *t[6] = { &p1, &p2, &a1, &a2, &a3, &l }; + cout << "------------------------------------------" << endl; + cout << "上述教师的基本信息为:" << endl; + for (int i = 0; i < 6; i++) { + t[i]->pay(); + t[i]->display(); + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/9/1.cpp b/Practical-Teaching/OPP-in-C++/9/1.cpp new file mode 100644 index 0000000..73b16f2 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/9/1.cpp @@ -0,0 +1,111 @@ +// 定义一个有理数类。一个有理数类是一个可以表示成两个整数相除的数,如1/2、2/3、4/5。一个有理数类有两个整数成员表示:分子和分母。要求能检测分母为0问题,能化简,重载+、-、*、/运算符完成四则运算,重载“==”符号判断两个有理数是否相等 + +#include + +using namespace std; + +class Rational { +private: + int numerator; + int denominator; + +public: + Rational(int num, int den); + Rational operator+(const Rational &r) const; + Rational operator-(const Rational &r) const; + Rational operator*(const Rational &r) const; + Rational operator/(const Rational &r) const; + bool operator==(const Rational &r) const; + friend ostream &operator<<(ostream &output, const Rational &r); +}; + +Rational::Rational(int num, int den) { + numerator = num; + denominator = den; + if (numerator == 0 && denominator == 0) + ; + else if (numerator == 0) + denominator = 1; + else if (denominator == 0) + numerator = 1; + else { + int _gcd = gcd(numerator, denominator); + numerator /= _gcd; + denominator /= _gcd; + if (denominator < 0) { + numerator *= -1; + denominator *= -1; + } + } +} + +Rational Rational::operator+(const Rational &r) const { + int num, den; + if (numerator != 0 && r.numerator != 0 && denominator == 0 && r.denominator == 0) { + num = 1; + den = 0; + } + else { + num = numerator * r.denominator + r.numerator * denominator; + den = denominator * r.denominator; + } + return Rational(num, den); +} + +Rational Rational::operator-(const Rational &r) const { + int num = numerator * r.denominator - r.numerator * denominator; + int den = denominator * r.denominator; + return Rational(num, den); +} + +Rational Rational::operator*(const Rational &r) const { + int num = numerator * r.numerator; + int den = denominator * r.denominator; + return Rational(num, den); +} + +Rational Rational::operator/(const Rational &r) const { + int num, den; + if (denominator == 0 && r.denominator == 0) { + num = 0; + den = 0; + } + else { + num = numerator * r.denominator; + den = r.numerator * denominator; + } + return Rational(num, den); +} + +bool Rational::operator==(const Rational &r) const { + return numerator == r.numerator && denominator == r.denominator; +} + +ostream &operator<<(ostream &output, const Rational &r) { + if (r.numerator == 0 && r.denominator == 0) + output << "NaN"; + else if (r.denominator == 0) + output << "Inf"; + else + output << r.numerator << " / " << r.denominator; + return output; +} + +int main() { + char c; + int num1, den1, num2, den2; + cout << "r1 = "; + cin >> num1 >> c >> den1; + cout << "r2 = "; + cin >> num2 >> c >> den2; + Rational r1(num1, den1), r2(num2, den2); + cout << "r1 + r2 = " << r1 + r2 << endl + << "r1 - r2 = " << r1 - r2 << endl + << "r1 * r2 = " << r1 * r2 << endl + << "r1 / r2 = " << r1 / r2 << endl; + if (r1 == r2) + cout << "r1 == r2" << endl; + else + cout << "r1 != r2" << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/OPP-in-C++/9/2.cpp b/Practical-Teaching/OPP-in-C++/9/2.cpp new file mode 100644 index 0000000..0c9d259 --- /dev/null +++ b/Practical-Teaching/OPP-in-C++/9/2.cpp @@ -0,0 +1,99 @@ +// 改造Set类,重载+(并集)、(-)差集、*(交集)、<<(输出)、>>(输入)和函数调用操作符(添加一个元素) + +#include + +using namespace std; + +class Set { +private: + vector a; + +public: + int search(int); + int operator()(int x); + int del(int); + Set operator*(Set &); + Set operator+(Set &); + Set operator-(Set &); + friend ostream &operator<<(ostream &output, const Set &s); + friend istream &operator>>(istream &input, Set &s); +}; + +int Set::search(int x) { + for (int i = 0; i < a.size(); i++) + if (a[i] == x) + return i; + return -1; +} + +int Set::operator()(int x) { + if (search(x) != -1) + return 0; + a.push_back(x); + return 1; +} + +int Set::del(int x) { + int i = search(x); + if (i == -1) + return 0; + a.erase(a.begin() + i); + return 1; +} + +Set Set::operator*(Set &s) { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) != -1) + t(a[i]); + return t; +} + +Set Set::operator+(Set &s) { + Set t = *this; + for (int i = 0; i < s.a.size(); i++) + t(s.a[i]); + return t; +} + +Set Set::operator-(Set &s) { + Set t; + for (int i = 0; i < a.size(); i++) + if (s.search(a[i]) == -1) + t(a[i]); + return t; +} + +ostream &operator<<(ostream &output, const Set &s) { + for (int i = 0; i < s.a.size(); i++) { + output << s.a[i] << ' '; + } + return output; +} + +istream &operator>>(istream &input, Set &s) { + s.a.clear(); + int x; + while (input >> x) { + s(x); + } + return input; +} + +int main() { + Set s1, s2; + cout << "s1: "; + cin >> s1; + s2(9); + s2(10); + s2(11); + s2(12); + s2(13); + s2(14); + s2(15); + cout << "s2: " << s2 << endl; + cout << "s1 * s2: " << s1 * s2 << endl; + cout << "s1 + s2: " << s1 + s2 << endl; + cout << "s1 - s2: " << s1 - s2 << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/1.1.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/1.1.cpp new file mode 100644 index 0000000..646a6d2 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/1.1.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 定义一个函数,用于计算表达式的值 +double Evalue(stringstream &exp) { + string e; + exp >> e; + // 如果是加法 + if (e == "add") + // 递归计算左右两个操作数的值并相加 + return Evalue(exp) + Evalue(exp); + // 如果是减法 + else if (e == "sub") + // 递归计算左右两个操作数的值并相减 + return Evalue(exp) - Evalue(exp); + // 如果是乘法 + else if (e == "muti") + // 递归计算左右两个操作数的值并相乘 + return Evalue(exp) * Evalue(exp); + // 如果是除法 + else if (e == "div") + // 递归计算左右两个操作数的值并相除 + return Evalue(exp) / Evalue(exp); + // 如果是取负 + else if (e == "neg") { + double temp; + exp >> temp; + // 取负并返回 + return -temp; + } + // 如果是平方 + else if (e == "doubleMe") { + double temp; + exp >> temp; + // 平方并返回 + return temp * temp; + } + // 如果是数字 + else + // 直接返回数字 + return atof(e.c_str()); +} + +int main() { + // 从文件中读取表达式 + ifstream fin("E:\\OneDrive\\Code\\C++\\Professional-Comprehensive-Training-I\\question.txt"); + // 将计算结果写入文件 + ofstream fout("E:\\OneDrive\\Code\\C++\\Professional-Comprehensive-Training-I\\answer.txt"); + string line; + while (getline(fin, line)) { + string temp = line; + // 将括号和逗号替换为空格 + for (char &c : temp) + if (c == '(' || c == ')' || c == ',') + c = ' '; + // 将表达式转换为流并计算结果 + stringstream exp(temp); + fout << line << " = " << Evalue(exp) << endl; + } + // 关闭文件 + fin.close(); + fout.close(); + return 0; +} diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/1.2.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/1.2.cpp new file mode 100644 index 0000000..6cfe3ce --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/1.2.cpp @@ -0,0 +1,155 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 定义节点结构体 +struct Node { + char operato; // 运算符 + double operand; // 操作数 + Node *left; // 左子树 + Node *right; // 右子树 + Node(char o = 0, double d = 0, Node *l = nullptr, Node *r = nullptr) : operato(o), operand(d), left(l), right(r) {} +}; + +// 定义树类型 +using Tree = Node *; + +// 递归构建表达式树 +Tree buildTree(stringstream &ss) { + string e; + ss >> e; + // 如果是加法 + if (e == "add") { + Tree t = new Node('+'); + t->left = buildTree(ss); + t->right = buildTree(ss); + return t; + } + // 如果是减法 + else if (e == "sub") { + Tree t = new Node('-'); + t->left = buildTree(ss); + t->right = buildTree(ss); + return t; + } + // 如果是乘法 + else if (e == "muti") { + Tree t = new Node('*'); + t->left = buildTree(ss); + t->right = buildTree(ss); + return t; + } + // 如果是除法 + else if (e == "div") { + Tree t = new Node('/'); + t->left = buildTree(ss); + t->right = buildTree(ss); + return t; + } + // 如果是取负 + else if (e == "neg") { + double temp; + ss >> temp; + return new Node(0, -temp); + } + // 如果是平方 + else if (e == "doubleMe") { + Tree t = new Node('^'); + double temp; + ss >> temp; + t->left = new Node(0, temp); + t->right = new Node(0, 2); + return t; + } + // 如果是数字 + else + return new Node(0, atof(e.c_str())); +} + +// 判断节点是否为运算符 +bool isOperator(const Tree t) { + return t->operato != 0; +} + +// 定义运算符优先级 +map priority{ { '+', 1 }, { '-', 1 }, { '*', 2 }, { '/', 2 }, { '^', 3 } }; + +// 判断运算符优先级是否小于等于另一个运算符 +bool lowerOrEqualPrecedence(const char op1, const char op2) { + return priority[op1] <= priority[op2]; +} + +// 输出表达式树 +void print(ostream &out, const Tree t = nullptr) { + if (t == nullptr) + return; + if (isOperator(t)) { + bool leftParen = isOperator(t->left) && lowerOrEqualPrecedence(t->left->operato, t->operato); + bool rightParen = isOperator(t->right) && lowerOrEqualPrecedence(t->right->operato, t->operato); + if (leftParen) + out << "("; + print(out, t->left); + if (leftParen) + out << ")"; + out << ' ' << t->operato << ' '; + if (rightParen) + out << "("; + print(out, t->right); + if (rightParen) + out << ")"; + } + else + out << t->operand; +} + +// 计算表达式树的值 +double evaluate(const Tree t) { + if (t == nullptr) + return 0; + if (isOperator(t)) { + double left = evaluate(t->left); + double right = evaluate(t->right); + switch (t->operato) { + case '+': + return left + right; + case '-': + return left - right; + case '*': + return left * right; + case '/': + return left / right; + case '^': + return pow(left, right); + } + } + return t->operand; +} + +int main() { + // 从文件中读取表达式 + ifstream fin("E:\\OneDrive\\Code\\C++\\Professional-Comprehensive-Training-I\\question.txt"); + // 将计算结果写入文件 + ofstream fout("E:\\OneDrive\\Code\\C++\\Professional-Comprehensive-Training-I\\answer.txt"); + string line; + while (getline(fin, line)) { + string temp = line; + // 将括号和逗号替换为空格 + for (char &c : temp) + if (c == '(' || c == ')' || c == ',') + c = ' '; + // 将表达式转换为流并构建表达式树 + stringstream ss(temp); + Tree t = buildTree(ss); + // 输出表达式和计算结果 + print(fout, t); + fout << " = " << evaluate(t); + fout << endl; + } + // 关闭文件 + fin.close(); + fout.close(); + return 0; +} diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/1.4.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/1.4.cpp new file mode 100644 index 0000000..b223a82 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/1.4.cpp @@ -0,0 +1,322 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 定义一个结构体,表示一条记录 +struct Record { + int id; // 记录的id + string name; // 记录的名字 + bool isMale; // 记录的性别 + double data; // 记录的数据 + Record(int id = 0, string name = "", bool isMale = true, double data = 0) : id(id), name(name), isMale(isMale), data(data) {} +}; + +// 定义一个比较函数对象,用于将记录按照id从小到大排序 +struct cmp { + bool operator()(const Record &a, const Record &b) const { + return a.id < b.id; + } +}; + +// 从输入流in中读取记录,将记录插入到set中并返回 +set table(istream &in) { + set table; // 定义一个set,用于存储记录 + while (!in.eof()) // 循环读取输入流中的记录 + { + int id; + string name, gender; + bool isMale; + double data; + in >> id >> name >> gender >> data; // 从输入流中读取记录的各个字段 + if (gender == "male") // 判断记录的性别 + isMale = true; + else + isMale = false; + table.insert(Record(id, name, isMale, data)); // 将记录插入到set中 + } + return table; // 返回set +} + +int main() { + string sql; + while (getline(cin, sql)) // 从标准输入读取一行 SQL 语句 + { + ifstream sfin("stu.txt"), efin("employee.txt"); // 打开两个文件 + if (!sfin.is_open() || !efin.is_open()) // 如果文件打开失败 + { + cout << "File not found!" << endl; // 输出错误信息 + return 0; // 退出程序 + } + set stu = table(sfin), employee = table(efin); // 从文件中读取数据并存储到 set 容器中 + sfin.close(), efin.close(); // 关闭文件 + if (sql == "EXIT") // 如果输入的 SQL 语句为 EXIT + break; // 退出循环 + stringstream ss(sql); // 将 SQL 语句转换为 stringstream 流 + string tmp; + bool col[4], isStu, isMale; + double limits; + ss >> tmp; + if (tmp != "SELECT") // 如果 SQL 语句不是 SELECT + { + cout << "Invalid SQL!" << endl; // 输出错误信息 + continue; // 继续下一次循环 + } + ss >> tmp; + if (tmp == "*") // 如果 SQL 语句为 SELECT * + { + for (bool &b : col) + b = true; // 将 col 数组中的所有元素都设置为 true + ss >> tmp; + } + else { + bool conti = false; + for (bool &b : col) + b = false; // 将 col 数组中的所有元素都设置为 false + do { + if (tmp == "ID" || tmp == "ID,") + col[0] = true; // 如果 SQL 语句中包含 ID,将 col[0] 设置为 true + else if (tmp == "Name" || tmp == "Name,") + col[1] = true; // 如果 SQL 语句中包含 Name,将 col[1] 设置为 true + else if (tmp == "Gender" || tmp == "Gender,") + col[2] = true; // 如果 SQL 语句中包含 Gender,将 col[2] 设置为 true + else if (tmp == "Score" || tmp == "Score," || tmp == "Salary" || tmp == "Salary,") + col[3] = true; // 如果 SQL 语句中包含 Score 或 Salary,将 col[3] 设置为 true + else { + if (tmp != "FROM") { + cout << "The type of data does not exist!" << endl; // 输出错误信息 + conti = true; // 设置 conti 为 true + } + break; + } + } while (ss >> tmp); + if (conti) + continue; // 继续下一次循环 + } + if (tmp != "FROM") // 如果 SQL 语句不是 FROM + { + cout << "Invalid SQL!" << endl; // 输出错误信息 + continue; // 继续下一次循环 + } + else { + ss >> tmp; + if (tmp != "stu" && tmp != "employee") // 如果 SQL 语句中不包含 stu 或 employee + { + cout << "The table does not exist!" << endl; // 输出错误信息 + continue; // 继续下一次循环 + } + else { + isStu = tmp == "stu"; // 如果 SQL 语句中包含 stu,将 isStu 设置为 true,否则设置为 false + } + } + if (ss >> tmp) // 如果 SQL 语句中包含 WHERE + { + if (tmp != "WHERE") // 如果 SQL 语句中 WHERE 后面不是条件 + { + cout << "Invalid SQL!" << endl; // 输出错误信息 + continue; // 继续下一次循环 + } + else { + bool conti = false; + while (ss >> tmp) { + if (tmp == "Score" || tmp == "Salary") // 如果 SQL 语句中包含 Score 或 Salary + { + ss >> tmp; + if (tmp == ">=") { + ss >> limits; + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->data < limits) + it = stu.erase(it); // 如果数据小于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->data < limits) + it = employee.erase(it); // 如果数据小于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else if (tmp == "<=") { + ss >> limits; + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->data > limits) + it = stu.erase(it); // 如果数据大于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->data > limits) + it = employee.erase(it); // 如果数据大于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else if (tmp == "=") { + ss >> limits; + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->data != limits) + it = stu.erase(it); // 如果数据不等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->data != limits) + it = employee.erase(it); // 如果数据不等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else if (tmp == "<") { + ss >> limits; + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->data >= limits) + it = stu.erase(it); // 如果数据大于等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->data >= limits) + it = employee.erase(it); // 如果数据大于等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else if (tmp == ">") { + ss >> limits; + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->data <= limits) + it = stu.erase(it); // 如果数据小于等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->data <= limits) + it = employee.erase(it); // 如果数据小于等于 limits,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else { + cout << "Invalid SQL!" << endl; // 输出错误信息 + conti = true; // 设置 conti 为 true + continue; + } + } + else if (tmp == "Gender") // 如果 SQL 语句中包含 Gender + { + ss >> tmp; + if (tmp != "=") { + cout << "Invalid SQL!" << endl; // 输出错误信息 + conti = true; // 设置 conti 为 true + continue; + } + ss >> tmp; + if (tmp == "male") + isMale = true; // 如果 SQL 语句中包含 male,将 isMale 设置为 true + else if (tmp == "female") + isMale = false; // 如果 SQL 语句中包含 female,将 isMale 设置为 false + else { + cout << "Invalid SQL!" << endl; // 输出错误信息 + conti = true; // 设置 conti 为 true + continue; + } + if (isStu) { + for (auto it = stu.begin(); it != stu.end();) { + if (it->isMale != isMale) + it = stu.erase(it); // 如果数据的性别与 isMale 不同,将该数据从 set 容器中删除 + else + ++it; + } + } + else { + for (auto it = employee.begin(); it != employee.end();) { + if (it->isMale != isMale) + it = employee.erase(it); // 如果数据的性别与 isMale 不同,将该数据从 set 容器中删除 + else + ++it; + } + } + } + else if (tmp == "AND") + continue; // 如果 SQL 语句中包含 AND,继续下一次循环 + else { + cout << "Invalid SQL!" << endl; // 输出错误信息 + conti = true; // 设置 conti 为 true + continue; + } + } + if (conti) + continue; // 继续下一次循环 + } + } + if (isStu) // 如果 SQL 语句中包含 stu + { + if (col[0]) + cout << "ID "; + if (col[1]) + cout << "Name "; + if (col[2]) + cout << "Gender "; + if (col[3]) + cout << "Score "; + cout << endl; + for (auto it = stu.begin(); it != stu.end(); ++it) { + if (col[0]) + cout << it->id << " "; + if (col[1]) + cout << it->name << " "; + if (col[2]) + cout << (it->isMale ? "male" : "female") << " "; + if (col[3]) + cout << it->data << " "; + cout << endl; + } + } + else // 如果 SQL 语句中包含 employee + { + if (col[0]) + cout << "ID "; + if (col[1]) + cout << "Name "; + if (col[2]) + cout << "Gender "; + if (col[3]) + cout << "Salary "; + cout << endl; + for (auto it = employee.begin(); it != employee.end(); ++it) { + if (col[0]) + cout << it->id << " "; + if (col[1]) + cout << it->name << " "; + if (col[2]) + cout << (it->isMale ? "male" : "female") << " "; + if (col[3]) + cout << it->data << " "; + cout << endl; + } + } + } +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/1.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/1.cpp new file mode 100644 index 0000000..7f720ec --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/1.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 递归计算表达式的值 +double Evalue(const string &exp, int &pos) { + char e = exp[pos]; // 取出当前位置的字符 + switch (e) // 根据字符类型进行不同的计算 + { + case '+': + return Evalue(exp, ++pos) + Evalue(exp, ++pos); // 如果是加号,则计算左右两边表达式的值之和 + case '-': + return Evalue(exp, ++pos) - Evalue(exp, ++pos); // 如果是减号,则计算左右两边表达式的值之差 + case '*': + return Evalue(exp, ++pos) * Evalue(exp, ++pos); // 如果是乘号,则计算左右两边表达式的值之积 + case '/': + return Evalue(exp, ++pos) / Evalue(exp, ++pos); // 如果是除号,则计算左右两边表达式的值之商 + default: + return e - '0'; // 如果是数字,则返回该数字的值 + } +} + +int main() { + string exp; + cin >> exp; + int pos = 0; + cout << Evalue(exp, pos) << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/2.1.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/2.1.cpp new file mode 100644 index 0000000..c4c2646 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/2.1.cpp @@ -0,0 +1,139 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 定义一个图类 +class Graph { +private: + int n, e; // n表示图中顶点的个数,e表示图中边的个数 + int **adj; // 邻接矩阵 + +public: + Graph(istream &in); // 构造函数,从输入流中读取图的信息 + ~Graph(); // 析构函数,释放邻接矩阵的内存 + int getn() const { + return n; + } // 返回图中顶点的个数 + void print() const; // 打印邻接矩阵 + bool bfs(int u, int v) const; // 判断从顶点u到顶点v是否存在一条路径,使用广度优先搜索算法 + bool dfs(int u, int v, bool *visited) const; // 判断从顶点u到顶点v是否存在一条路径,使用深度优先搜索算法 + bool **warshall() const; // 计算图的传递闭包,使用Warshall算法 +}; + +// 构造函数,从输入流in中读取图的信息 +Graph::Graph(istream &in) { + in >> n >> e; // 读取顶点数和边数 + adj = new int *[n]; // 动态分配邻接矩阵的内存 + for (size_t i = 0; i < n; i++) { + adj[i] = new int[n]; + for (size_t j = 0; j < n; j++) + adj[i][j] = 0; // 初始化邻接矩阵 + } + for (size_t i = 0; i < e; i++) { + int u, v; + in >> u >> v; + adj[u - 1][v - 1]++; // 读取边的信息,更新邻接矩阵 + } +} + +// 析构函数,释放邻接矩阵的内存 +Graph::~Graph() { + for (size_t i = 0; i < n; i++) + delete[] adj[i]; + delete[] adj; +} + +// 打印邻接矩阵 +void Graph::print() const { + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) + cout << adj[i][j] << " "; + cout << endl; + } +} + +// 判断从顶点u到顶点v是否存在一条路径,使用广度优先搜索算法 +bool Graph::bfs(int u, int v) const { + if (u == v) + return true; + queue q; + bool visited[n]; + memset(visited, false, sizeof(visited)); + q.push(u); + visited[u] = true; + while (!q.empty()) { + int w = q.front(); + q.pop(); + for (size_t i = 0; i < n; i++) + if (adj[w][i] && !visited[i]) { + if (i == v) + return true; + q.push(i); + visited[i] = true; + } + } + return false; +} + +// 判断从顶点u到顶点v是否存在一条路径,使用深度优先搜索算法 +bool Graph::dfs(int u, int v, bool *visited) const { + if (u == v) + return true; + visited[u] = true; + for (size_t i = 0; i < n; i++) + if (adj[u][i] && !visited[i]) + if (dfs(i, v, visited)) + return true; + return false; +} + +// 计算图的传递闭包,使用Warshall算法 +bool **Graph::warshall() const { + bool **rch = new bool *[n]; + for (size_t i = 0; i < n; i++) { + rch[i] = new bool[n]; + for (size_t j = 0; j < n; j++) + rch[i][j] = adj[i][j]; + rch[i][i] = true; + } + for (size_t k = 0; k < n; k++) + for (size_t i = 0; i < n; i++) + for (size_t j = 0; j < n; j++) + rch[i][j] = rch[i][j] || (rch[i][k] && rch[k][j]); + return rch; +} + +// 主函数 +int main() { + ifstream fin("graph.txt"); // 打开文件 + Graph g(fin); // 创建图对象 + fin.close(); // 关闭文件 + cout << "Adjacency matrix:" << endl; + g.print(); // 打印邻接矩阵 + cout << "BFS:" << endl; + for (size_t i = 0; i < g.getn(); i++) { + for (size_t j = 0; j < g.getn(); j++) + cout << g.bfs(i, j) << " "; // 判断从顶点i到顶点j是否存在一条路径,使用广度优先搜索算法 + cout << endl; + } + cout << "DFS:" << endl; + for (size_t i = 0; i < g.getn(); i++) { + for (size_t j = 0; j < g.getn(); j++) { + bool visited[g.getn()]; + memset(visited, false, sizeof(visited)); + cout << g.dfs(i, j, visited) << " "; // 判断从顶点i到顶点j是否存在一条路径,使用深度优先搜索算法 + } + cout << endl; + } + cout << "Warshall:" << endl; + bool **rch = g.warshall(); // 计算图的传递闭包,使用Warshall算法 + for (size_t i = 0; i < g.getn(); i++) { + for (size_t j = 0; j < g.getn(); j++) + cout << rch[i][j] << " "; + cout << endl; + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/2.2.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/2.2.cpp new file mode 100644 index 0000000..aa44ca4 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/2.2.cpp @@ -0,0 +1,106 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph { +private: + int n; // 图的顶点数 + int **adj; // 邻接矩阵 + +public: + Graph(istream &in); // 构造函数,从输入流in中读取邻接矩阵 + ~Graph(); // 析构函数,释放邻接矩阵的内存 + int tsp(); // TSP 算法,计算最短哈密顿回路 + void tsp_backtrack(int k, int *path, int *visited, int &min_path); // 回溯法 + int path_len(int *path, int k); // 计算路径长度 +}; + +Graph::Graph(istream &in) { + in >> n; // 读取顶点数 + adj = new int *[n]; // 动态分配二维数组 + for (size_t i = 0; i < n; i++) { + adj[i] = new int[n]; + } + for (size_t i = 0; i < n; i++) { + adj[i][i] = 0; // 对角线上的元素为0 + for (int j = i + 1; j < n; j++) { + in >> adj[i][j]; // 读取邻接矩阵 + adj[j][i] = adj[i][j]; // 邻接矩阵是对称矩阵 + } + } +} + +Graph::~Graph() { + for (size_t i = 0; i < n; ++i) + delete[] adj[i]; // 释放每一行的内存 + delete[] adj; // 释放二维数组的内存 +} + +int Graph::tsp() { + int *path = new int[n]; // 存储当前的路径 + int *visited = new int[n]; // 存储已经访问过的顶点 + int min_path = INT_MAX; // 存储最短路径长度 + + // 初始化 + for (int i = 0; i < n; i++) { + visited[i] = 0; + } + visited[0] = 1; + path[0] = 0; + + // 回溯 + tsp_backtrack(1, path, visited, min_path); + + // 释放内存 + delete[] path; + delete[] visited; + + return min_path; +} + +void Graph::tsp_backtrack(int k, int *path, int *visited, int &min_path) { + if (k == n) // 所有的顶点都已经遍历完了 + { + int path_len = 0; + for (int i = 0; i < n - 1; i++) { + path_len += adj[path[i]][path[i + 1]]; + } + path_len += adj[path[n - 1]][0]; // 回到起点 + if (path_len < min_path) { + min_path = path_len; + } + return; + } + + for (int i = 0; i < n; i++) { + if (!visited[i]) { + path[k] = i; + visited[i] = 1; + if (path_len(path, k) < min_path) // 剪枝 + { + tsp_backtrack(k + 1, path, visited, min_path); + } + visited[i] = 0; + } + } +} + +int Graph::path_len(int *path, int k) { + int len = 0; + for (int i = 0; i < k - 1; i++) { + len += adj[path[i]][path[i + 1]]; + } + len += adj[path[k - 1]][0]; // 回到起点 + return len; +} + +int main() { + ifstream fin("adj.txt"); // 打开输入文件 + Graph g(fin); // 创建图 + fin.close(); // 关闭输入文件 + cout << g.tsp() << endl; // 计算最短哈密顿回路并输出 + return 0; +} diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/2.4.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/2.4.cpp new file mode 100644 index 0000000..672b3f0 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/2.4.cpp @@ -0,0 +1,80 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph { +private: + int n; // 图的顶点数 + int **adj; // 邻接矩阵 + +public: + Graph(istream &in); // 构造函数,从输入流in中读取邻接矩阵 + ~Graph(); // 析构函数,释放邻接矩阵的内存 + void floyd() const; // Floyd算法,计算任意两点之间的最短路径 +}; + +Graph::Graph(istream &in) { + in >> n; // 读取顶点数 + adj = new int *[n]; // 动态分配二维数组 + for (size_t i = 0; i < n; i++) { + adj[i] = new int[n]; + for (size_t j = 0; j < n; j++) + in >> adj[i][j]; // 读取邻接矩阵 + } +} + +Graph::~Graph() { + for (size_t i = 0; i < n; i++) + delete[] adj[i]; // 释放每一行的内存 + delete[] adj; // 释放二维数组的内存 +} + +void Graph::floyd() const { + int dist[n][n]; // 存储任意两点之间的最短距离 + int path[n][n]; // 存储任意两点之间的最短路径 + for (size_t i = 0; i < n; i++) + for (size_t j = 0; j < n; j++) { + dist[i][j] = adj[i][j]; // 初始化最短距离 + path[i][j] = j; // 初始化最短路径 + } + for (size_t k = 0; k < n; k++) + for (size_t i = 0; i < n; i++) + for (size_t j = 0; j < n; j++) + if (dist[i][k] + dist[k][j] < dist[i][j]) // 如果经过k点的路径更短 + { + dist[i][j] = dist[i][k] + dist[k][j]; // 更新最短距离 + path[i][j] = path[i][k]; // 更新最短路径 + } + for (size_t i = 0; i < n; i++) { + cout << "From " << i + 1 << ":" << endl; // 输出起点 + for (size_t j = 0; j < n; j++) { + if (i == j) + continue; + cout << "To " << j + 1 << ": "; + cout << i + 1 << " "; // 输出起点 + int k = path[i][j]; + while (k != j) // 输出路径上的中间点 + { + cout << k + 1 << " "; + k = path[k][j]; + } + cout << j + 1 << endl; // 输出终点 + } + cout << endl; + } +} + +int main() { + // 打开输入文件 + ifstream fin("adj.txt"); + // 创建图 + Graph g(fin); + // 关闭输入文件 + fin.close(); + // 计算任意两点之间的最短路径 + g.floyd(); + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/2.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/2.cpp new file mode 100644 index 0000000..d99ff6e --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/2.cpp @@ -0,0 +1,22 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +int main() { + ifstream fin("a.txt"); // 打开文件“a.txt”以读取模式 + ofstream fout("b.txt"); // 打开文件“b.txt”以写入模式 + string line; + while (getline(fin, line)) // 从文件“a.txt”中读取一行到 line 中 + { + for (char &c : line) // 遍历 line 中的每个字符 + if (c == '(' || c == ')' || c == ',') // 如果字符是“(”或“)”或“,” + c = ' '; // 将字符替换为空格 + fout << line << endl; // 将 line 写入文件“b.txt”中并换行 + } + fin.close(); // 关闭文件“a.txt” + fout.close(); // 关闭文件“b.txt” + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/3.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/3.cpp new file mode 100644 index 0000000..f31f563 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/3.cpp @@ -0,0 +1,102 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 同编程作业 1 +double Evalue(const string &exp, int &pos) { + char e = exp[pos]; + switch (e) { + case '+': + return Evalue(exp, ++pos) + Evalue(exp, ++pos); + case '-': + return Evalue(exp, ++pos) - Evalue(exp, ++pos); + case '*': + return Evalue(exp, ++pos) * Evalue(exp, ++pos); + case '/': + return Evalue(exp, ++pos) / Evalue(exp, ++pos); + default: + return e - '0'; + } +} + +// 定义二叉树节点结构体 +struct Node { + int data; // 节点数据 + Node *left; // 左子节点指针 + Node *right; // 右子节点指针 + Node(int d, Node *l = nullptr, Node *r = nullptr) : data(d), left(l), right(r) {} +}; + +// 定义二叉树类型别名 +using Tree = Node *; + +// 根据表达式构建二叉树 +Tree buildTree(const string &exp, int &pos) { + char e = exp[pos]; // 获取当前字符 + switch (e) { + case '+': + case '-': + case '*': + case '/': { + Tree t = new Node(e); // 创建一个新节点 + t->left = buildTree(exp, ++pos); // 递归构建左子树 + t->right = buildTree(exp, ++pos); // 递归构建右子树 + return t; + } + default: + return new Node(e - '0'); // 创建一个新节点,存储当前数字字符对应的数字 + } +} + +// 判断节点是否为运算符 +bool isOperator(const Tree t) { + return t->data == '+' || t->data == '-' || t->data == '*' || t->data == '/'; +} + +// 判断两个运算符的优先级关系 +bool lowerOrEqualPrecedence(const char op1, const char op2) { + if (op1 == '+' || op1 == '-') + return true; + if (op1 == '*' || op1 == '/') + return op2 == '*' || op2 == '/'; + return false; +} + +// 中序遍历二叉树并输出表达式 +void print(const Tree t) { + if (t == nullptr) + return; + if (isOperator(t)) // 如果当前节点是运算符 + { + bool leftParen = isOperator(t->left) && lowerOrEqualPrecedence(t->left->data, t->data); // 判断左子节点是否需要加括号 + bool rightParen = isOperator(t->right) && lowerOrEqualPrecedence(t->right->data, t->data); // 判断右子节点是否需要加括号 + if (leftParen) + cout << "("; // 输出左括号 + print(t->left); // 递归输出左子树 + if (leftParen) + cout << ")"; // 输出右括号 + cout << (char)t->data; // 输出当前运算符 + if (rightParen) + cout << "("; // 输出左括号 + print(t->right); // 递归输出右子树 + if (rightParen) + cout << ")"; // 输出右括号 + } + else + cout << t->data; // 如果当前节点是数字,直接输出 +} + +int main() { + string exp; + cin >> exp; + int pos = 0; + cout << Evalue(exp, pos) << endl; + pos = 0; + Tree t = buildTree(exp, pos); + print(t); + cout << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/4.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/4.cpp new file mode 100644 index 0000000..7dc217f --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/4.cpp @@ -0,0 +1,104 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +map priority{ { '+', 1 }, { '-', 1 }, { '*', 2 }, { '/', 2 } }; + +double Evalue(const string &s) { + stack num; // 存储数字的栈 + stack op; // 存储运算符的栈 + int i = 0; + while (i < s.size()) { + if (s[i] == ' ') // 如果是空格则跳过 + { + i++; + continue; + } + if (isdigit(s[i])) // 如果是数字则将其转换为 double 类型并压入数字栈 + { + double temp = 0; + while (i < s.size() && isdigit(s[i])) { + temp = temp * 10 + s[i] - '0'; + i++; + } + num.push(temp); + } + else if (s[i] == '(') // 如果是左括号则将其压入运算符栈 + { + op.push(s[i]); + i++; + } + else if (s[i] == ')') // 如果是右括号则进行运算 + { + while (op.top() != '(') // 直到遇到左括号为止 + { + double b = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + double a = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + char c = op.top(); // 取出运算符栈的栈顶元素 + op.pop(); // 弹出运算符栈的栈顶元素 + if (c == '+') // 进行加法运算 + num.push(a + b); + else if (c == '-') // 进行减法运算 + num.push(a - b); + else if (c == '*') // 进行乘法运算 + num.push(a * b); + else if (c == '/') // 进行除法运算 + num.push(a / b); + } + op.pop(); // 弹出左括号 + i++; + } + else // 如果是运算符则进行运算 + { + while (!op.empty() && op.top() != '(' && priority[op.top()] >= priority[s[i]]) // 如果运算符栈不为空且栈顶元素不是左括号且当前运算符的优先级小于等于栈顶运算符的优先级 + { + double b = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + double a = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + char c = op.top(); // 取出运算符栈的栈顶元素 + op.pop(); // 弹出运算符栈的栈顶元素 + if (c == '+') // 进行加法运算 + num.push(a + b); + else if (c == '-') // 进行减法运算 + num.push(a - b); + else if (c == '*') // 进行乘法运算 + num.push(a * b); + else if (c == '/') // 进行除法运算 + num.push(a / b); + } + op.push(s[i]); // 将当前运算符压入运算符栈 + i++; + } + } + while (!op.empty()) // 如果运算符栈不为空则进行运算 + { + double b = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + double a = num.top(); // 取出数字栈的栈顶元素 + num.pop(); // 弹出数字栈的栈顶元素 + char c = op.top(); // 取出运算符栈的栈顶元素 + op.pop(); // 弹出运算符栈的栈顶元素 + if (c == '+') // 进行加法运算 + num.push(a + b); + else if (c == '-') // 进行减法运算 + num.push(a - b); + else if (c == '*') // 进行乘法运算 + num.push(a * b); + else if (c == '/') // 进行除法运算 + num.push(a / b); + } + return num.top(); // 返回数字栈的栈顶元素 +} + +int main() { + string s; + getline(cin, s); + cout << Evalue(s) << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/5.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/5.cpp new file mode 100644 index 0000000..0632dea --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/5.cpp @@ -0,0 +1,84 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +// 定义记录结构体 +struct Record { + int id; // 学号 + string name; // 姓名 + bool isMale; // 性别 + double score; // 成绩 + Record(int id = 0, string name = "", bool isMale = true, double score = 0) : id(id), name(name), isMale(isMale), score(score) {} +}; + +// 定义比较函数 +struct cmp { + bool operator()(const Record &a, const Record &b) const { + return a.id < b.id; + } +}; + +int main() { + // 定义记录集合 + set records; + // 读取文件 + ifstream fin("E:\\OneDrive\\Code\\C++\\data.txt"); + string ignore; + getline(fin, ignore); + // 逐行读取文件 + while (!fin.eof()) { + int id; + string name, gender; + bool isMale; + double score; + fin >> id >> name >> gender >> score; + // 判断性别 + if (gender == "男") + isMale = true; + else + isMale = false; + // 添加记录 + records.insert(Record(id, name, isMale, score)); + } + fin.close(); + // 定义列标志数组 + bool col[4]; + for (bool &b : col) + b = false; + double floorscore; + char t; + // 读取列标志和分数 + while (cin >> t, isdigit(t)) + col[t - '0' - 1] = true; + cin >> floorscore; + // 输出表头 + if (col[0]) + cout << "学号\t"; + if (col[1]) + cout << "姓名\t"; + if (col[2]) + cout << "性别\t"; + if (col[3]) + cout << "成绩" << endl; + // 输出符合条件的记录 + for (const Record &r : records) + if (r.score >= floorscore) { + if (col[0]) + cout << r.id << "\t"; + if (col[1]) + cout << r.name << "\t"; + if (col[2]) { + if (r.isMale) + cout << "男\t"; + else + cout << "女\t"; + } + if (col[3]) + cout << r.score; + cout << endl; + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/6.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/6.cpp new file mode 100644 index 0000000..8d88924 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/6.cpp @@ -0,0 +1,57 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph // 定义 Graph 类 +{ +private: + int n, e; // n 表示节点数,e 表示边数 + int **adj; // 邻接矩阵 + +public: + Graph(istream &in); // 构造函数 + int cnt2(); // 计算邻接矩阵的平方中边的数量 +}; + +Graph::Graph(istream &in) // 构造函数实现 +{ + in >> n >> e; // 读入节点数和边数 + adj = new int *[n]; // 动态分配邻接矩阵内存 + for (size_t i = 0; i < n; i++) // 初始化邻接矩阵 + { + adj[i] = new int[n]; + for (size_t j = 0; j < n; j++) + adj[i][j] = 0; + } + for (size_t i = 0; i < e; i++) // 读入边 + { + int u, v; + in >> u >> v; + adj[u - 1][v - 1]++; // 在邻接矩阵中标记边 + } +} + +int Graph::cnt2() // 计算长度为 2 的通路数 +{ + int adj2[n][n]; // 定义邻接矩阵的平方 + memset(adj2, 0, sizeof(adj2)); // 将邻接矩阵的平方初始化为 0 + for (int i = 0; i < n; i++) // 计算邻接矩阵的平方 + for (int j = 0; j < n; j++) + for (int k = 0; k < n; k++) + adj2[i][j] += adj[i][k] * adj[k][j]; + int cnt = 0; // 定义边的数量 + for (size_t i = 0; i < n; i++) // 统计边的数量 + for (size_t j = 0; j < n; j++) + cnt += adj2[i][j]; + return cnt; // 返回边的数量 +} + +int main() { + ifstream fin("E:\\OneDrive\\Code\\C++\\graph.txt"); // 打开文件 + Graph g(fin); // 创建 Graph 对象 g + cout << g.cnt2() << endl; // 输出 g 中的长度为 2 的通路数 + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/7.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/7.cpp new file mode 100644 index 0000000..64d23b5 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/7.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph // 定义 Graph 类 +{ +private: + int n, e; // n 表示节点数,e 表示边数 + int **adj; // 邻接矩阵 + +public: + Graph(istream &in); // 构造函数 + ~Graph(); // 析构函数 + int getn() { return n; } // 返回节点数 + void dfs(int v = 0, bool *visited = nullptr); // 深度优先搜索 +}; + +Graph::Graph(istream &in) // 构造函数实现 +{ + in >> n >> e; // 读入节点数和边数 + adj = new int *[n]; // 动态分配邻接矩阵内存 + for (size_t i = 0; i < n; i++) // 初始化邻接矩阵 + { + adj[i] = new int[n]; + for (size_t j = 0; j < n; j++) + adj[i][j] = 0; + } + for (size_t i = 0; i < e; i++) // 读入边 + { + int u, v; + in >> u >> v; + adj[u - 1][v - 1]++; // 在邻接矩阵中标记边 + } +} + +Graph::~Graph() // 析构函数实现 +{ + for (size_t i = 0; i < n; i++) // 释放邻接矩阵内存 + delete[] adj[i]; + delete[] adj; +} + +void Graph::dfs(int v, bool *visited) // 深度优先搜索实现 +{ + visited[v] = true; // 标记节点为已访问 + for (size_t i = 0; i < n; i++) // 遍历邻接矩阵 + if (adj[v][i] && !visited[i]) // 如果存在边且节点未被访问 + dfs(i, visited); // 递归访问节点 +} + +bool alltrue(bool *arr, int n) // 判断数组中所有元素是否为 true +{ + for (size_t i = 0; i < n; i++) + if (!arr[i]) + return false; + return true; +} + +int main() { + ifstream fin("graph.txt"); // 打开文件 + Graph g(fin); // 创建 Graph 对象 g + bool visited[g.getn()], outputed[g.getn()]; // 定义 visited 和 outputed 数组 + for (size_t i = 0; i < g.getn(); i++) // 初始化 visited 和 outputed 数组 + { + visited[i] = false; + outputed[i] = false; + } + int i = -1; // 初始化 i + while (!alltrue(outputed, g.getn())) // 如果 outputed 数组中有 false + { + while (visited[++i]) // 找到第一个未被访问的节点 + ; + g.dfs(i, visited); // 从该节点开始深度优先搜索 + for (size_t i = 0; i < g.getn(); i++) // 遍历 visited 数组 + if (visited[i] && !outputed[i]) // 如果节点被访问且未输出 + { + cout << i + 1 << " "; // 输出节点编号 + outputed[i] = true; // 标记节点为已输出 + } + cout << endl; + } + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/8.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/8.cpp new file mode 100644 index 0000000..544cb8c --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/8.cpp @@ -0,0 +1,66 @@ +// Copyright (c) 2023 Xi Xu +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph // 完全图类 +{ +private: + int n; // 节点数 + int **w; // 每条边的权值 + +public: + Graph(istream &in); // 构造函数,从输入流中读取图的信息 + ~Graph(); // 析构函数,释放内存 + int tsp(); // 求解 TSP 问题 +}; + +Graph::Graph(istream &in) { + in >> n; // 读取节点数 + w = new int *[n]; + for (size_t i = 0; i < n; i++) { + w[i] = new int[n]; + } + for (size_t i = 0; i < n; i++) // 读取每条边的权值 + { + w[i][i] = 0; // 对角线上的元素为 0 + for (int j = i + 1; j < n; j++) { + in >> w[i][j]; // 读取上三角元素 + w[j][i] = w[i][j]; // 下三角元素与上三角元素相等 + } + } +} + +Graph::~Graph() { + for (size_t i = 0; i < n; i++) + delete[] w[i]; + delete[] w; +} + +int Graph::tsp() // Graph 类的求解 TSP 问题的函数 +{ + int p[n]; // 存储节点的排列 + for (int i = 0; i < n; i++) + p[i] = i; // 初始排列为 0, 1, ..., n-1 + int min = INT_MAX; // 存储最小路径长度 + do // 枚举所有可能的排列 + { + int sum = 0; // 计算当前排列的路径长度 + for (int i = 0; i < n - 1; i++) + sum += w[p[i]][p[i + 1]]; + sum += w[p[n - 1]][p[0]]; + if (sum < min) // 更新最小路径长度 + min = sum; + } while (next_permutation(p, p + n)); // STL 中的排列生成函数 + return min; // 返回最小路径长度 +} + +int main() { + ifstream fin("graph.txt"); // 打开输入文件 + Graph g(fin); // 创建 Graph 类的对象 + fin.close(); // 关闭输入文件 + cout << g.tsp() << endl; // 求解 TSP 问题 + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/_2.3.cpp b/Practical-Teaching/Professional-Comprehensive-Training-I/_2.3.cpp new file mode 100644 index 0000000..9ad5784 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/_2.3.cpp @@ -0,0 +1,127 @@ +// Copyright (c) 2023 徐丞烨,王凯钦,宋析峰,杨崇新 +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +using namespace std; + +class Graph { +private: + int n, e; + int **adj; + +public: + Graph(istream &in); + ~Graph(); + void print() const; + bool isEulerian() const; + void dfs(int u, bool *visited, int v = 0, int w = 0) const; + bool isBridge(int u, int v) const; + void fleury() const; +}; + +Graph::Graph(istream &in) { + in >> n >> e; + adj = new int *[n]; + for (size_t i = 0; i < n; i++) { + adj[i] = new int[n]; + for (size_t j = 0; j < n; j++) + adj[i][j] = 0; + } + for (size_t i = 0; i < e; i++) { + int u, v; + in >> u >> v; + adj[u - 1][v - 1]++; + } +} + +Graph::~Graph() { + for (size_t i = 0; i < n; i++) + delete[] adj[i]; + delete[] adj; +} + +void Graph::print() const { + for (size_t i = 0; i < n; i++) { + for (size_t j = 0; j < n; j++) + cout << adj[i][j] << " "; + cout << endl; + } +} + +bool Graph::isEulerian() const { + for (size_t i = 0; i < n; i++) { + int sum = 0; + for (size_t j = 0; j < n; j++) + sum += adj[i][j]; + for (size_t j = 0; j < n; j++) + sum -= adj[j][i]; + if (sum != 0) + return false; + } + return true; +} + +void Graph::dfs(int u, bool *visited, int v, int w) const { + visited[u] = true; + for (size_t i = 0; i < n; i++) + if (adj[u][i] && !visited[i] && !(u == v && i == w)) + dfs(i, visited, v, w); +} + +bool Graph::isBridge(int u, int v) const { + if (adj[u][v] == 0) + return false; + int cnt = 0; + bool visited[n]; + memset(visited, false, sizeof(visited)); + for (size_t i = 0; i < n; i++) + if (!visited[i]) { + dfs(i, visited); + cnt++; + } + memset(visited, false, sizeof(visited)); + for (size_t i = 0; i < n; i++) + if (!visited[i]) { + dfs(i, visited, u, v); + cnt--; + } + return cnt < 0; +} + +void Graph::fleury() const { + int copyadj[n][n]; + for (size_t i = 0; i < n; i++) + for (size_t j = 0; j < n; j++) + copyadj[i][j] = adj[i][j]; + int u = 0; + while (true) { + cout << u + 1 << " "; + bool flag = false; + for (size_t v = 0; v < n; v++) + if (copyadj[u][v] && !isBridge(u, v)) { + copyadj[u][v]--; + u = v; + flag = true; + break; + } + if (!flag) + break; + } +} + +int main() { + ifstream fin("graph.txt"); + Graph g(fin); + fin.close(); + cout << "Adjacency matrix:" << endl; + g.print(); + bool is = g.isEulerian(); + if (g.isEulerian()) { + cout << "The graph is Eulerian." << endl; + g.fleury(); + } + else + cout << "The graph is not Eulerian." << endl; + return 0; +} \ No newline at end of file diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/adj.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/adj.txt new file mode 100644 index 0000000..ba97183 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/adj.txt @@ -0,0 +1,6 @@ +5 +0 1 3 8 1000 +1000 0 1000 1 1000 +1000 4 0 1000 1000 +1000 1000 1 0 3 +1000 1000 1000 1000 0 diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/answer.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/answer.txt new file mode 100644 index 0000000..9b0a262 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/answer.txt @@ -0,0 +1,4 @@ +23 + 45 = 68 +20 + (13 - 10) = 23 +(-4.6 - 12) + 2.4 ^ 2 * 5 = 12.2 +54 / (-3 + (9 - 3)) = 18 diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/employee.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/employee.txt new file mode 100644 index 0000000..66585f3 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/employee.txt @@ -0,0 +1,4 @@ +1001 Xiao male 1000 +1002 Hong female 1550 +1003 Li male 1865 +1004 Ming female 1691 diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/graph.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/graph.txt new file mode 100644 index 0000000..3888c84 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/graph.txt @@ -0,0 +1,8 @@ +5 7 +1 2 +1 3 +2 3 +2 4 +3 5 +5 1 +5 4 diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/question.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/question.txt new file mode 100644 index 0000000..aa4d353 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/question.txt @@ -0,0 +1,4 @@ +add(23, 45) +add(20, sub(13, 10)) +add(sub(neg(4.6), 12), muti(doubleMe(2.4), 5)) +div(54, add(-3, sub(9, 3))) diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/stu.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/stu.txt new file mode 100644 index 0000000..6f31422 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/stu.txt @@ -0,0 +1,4 @@ +1001 YCX male 100 +1002 WKQ female 99 +1003 SYF male 1000 +1004 XCY female 0 diff --git a/Practical-Teaching/Professional-Comprehensive-Training-I/tsp.txt b/Practical-Teaching/Professional-Comprehensive-Training-I/tsp.txt new file mode 100644 index 0000000..891a080 --- /dev/null +++ b/Practical-Teaching/Professional-Comprehensive-Training-I/tsp.txt @@ -0,0 +1,6 @@ +5 + +3 1 5 8 +6 7 9 +4 2 +3 \ No newline at end of file diff --git a/_del.bat b/_del.bat new file mode 100644 index 0000000..a942498 --- /dev/null +++ b/_del.bat @@ -0,0 +1,4 @@ +del *.exe /q /s +del a.out /q /s +del *.o /q /s +del tempCodeRunnerFile.ch /q /s