Should the children's shoes still remember the programming question "printing star patterns? It's just as beautiful as our programming childhood. The length of the printed side is n diamond, ho, and some people immediately write it out:
Package patterns. interpretation; public class figureprinting {/*** print the number of edges of the diamond pattern * @ Param n diamond Based on the given n value */Public void printdiamond (int n) {If (n <2) {Throw new illegalargumentexception ("parameter n =" + N + "error, the given parameter must be no less than 2! ");} Int midrow = n-1; For (int row = 0; row <= midrow; row ++) {printline (New int [] {midrow-row, midrow + row}, 2 * n-1, '*');} For (int row = midrow + 1; row <2 * n-1; row ++) {// symmetry: row = midrow + I and ROW = midrow-I have the same printline (New int [] {row-midrow, midrow + (2 * midrow-row )}, 2 * n-1, '*') ;}}/*** printline: print the symbol at a specified position; do not print the position of the symbol print space * @ Param indexes specifies the position array of the symbol to print * @ Param n a total of characters to print Number * @ Param symbol the symbol to print */Public void printline (INT [] indexes, int N, char symbol) {If (indexes = NULL | indexes. length = 0) {// if the position array is empty, wrap the system directly. out. println (); return;} If (n <indexes. length) {Throw new illegalargumentexception ("the number of characters to print exceeds the total number of characters in a row! ");} Int K = 0; For (INT I = 0; I <n; I ++) {if (I! = Indexes [k]) {system. out. printf ("% C", '');} else {system. out. printf ("% C", symbol); k ++; If (k = indexes. length) {for (I = indexes [k-1]; I <n; I ++) {system. out. printf ("% C", '') ;}}} system. out. println ();}}
Package patterns. interpretation; public class figureprintingtester {Private Static figureprinting fp = new figureprinting (); public static void testprintline () {FP. printline (null, 3, '*'); FP. printline (New int [0], 3, '*'); FP. printline (New int [] {}, 3, '*'); FP. printline (New int [3], 3, '*'); FP. printline (New int [] {2, 3}, '*'); FP. printline (New int [] {0, 1, 2}, 3, '*');} public static void testprintdiamond () {for (int K = 1; k <5; k ++) {try {system. out. printf ("diamond with a side length of % d: \ n", k); FP. printdiamond (k);} catch (exception e) {system. out. println (E. getmessage () ;}} public static void main (string [] ARGs) {testprintline (); testprintdiamond ();}}
However, there are some shortcomings in the above method:
1. There must be fine-grained control over the locations to be printed, and errors may occur if you are not careful. 2. There is almost no reusability. Once you want to print more complex or rule-less graphics, You need to redesign the control structure.
Is there any other solution?
Yes. Here we introduce the method and interpreter. The so-called recording method refers to the record or instruction of the position information of the pattern to be printed, while the interpreter parses the record or instruction. For example, print the symbol H.
X
X
X
It can be recorded as: 1 line 1x 3 blank 1x \ n 1 line 1x 1 blank 1x 1 blank 1x \ n 1 line 1x 3 blank 1x, or a brief note: 1l 1x 3B 1x \ n 1l1x1b1x1b1x \ n 1l 1x 3B 1x \ n. it is similar to the Travel length encoding. It seems that such a record-writing method is a little complicated, but its flexibility is very high. Almost any graph can write such a record-writing method, for 1x 1B 1x 1B... this common recording method can be generated by writing common routines.
In this way, the central task we need is converted into the rules for determining the log and the corresponding interpreter.
Based on the induction of various patterns, we can summarize several rules for describing a line of patterns:
1. the note can contain three components: (a) [valid values] [L or L], (B) [valid values] [B or B], (c) [valid value] [X or X]. The three components are separated by multiple space characters;
2. If the Line Mark L or l does not exist in the note method, it is regarded as a line note. If the note method only contains L or l, it is considered as one or more empty rows;
3. (a) always appears at the beginning. Next, (B) or (c) can appear in any combination or not.
The corresponding regular expression description is:
[Zero or multiple space characters] ([valid value] [ll])? [Zero or multiple space characters] ([combination of zero or multiple ([valid values] [bbxx] [zero or multiple spaces) [zero or multiple spaces].
The valid value is a value without leading zero, that is, [1-9] | [1-9] [0-9] +
The implementation code is as follows:
Package patterns. interpretation; import Java. util. imports; import Java. util. regEx. matcher; import Java. util. regEx. pattern; public class interpreter {Private Static final string part1_regex = "([1-9] | [1-9] [0-9] +) [ll])? "; Private Static final string part2_regex =" ([1-9] | [1-9] [0-9] +) [bbxx] \ s *)*) "; Private Static final string line_pattern_regex =" \ s * "+ part1_regex +" \ s * "+ part2_regex +" \ s *"; private Static final pattern line_pattern = pattern. compile (line_pattern_regex); Private Static final pattern part_pattern = pattern. compile ("([1-9] | [1-9] [0-9] +) ([bbxx])");/*** interpretfigure: explain the given graphic tag, which must be separated by \ n or \ r Mark multiple rows * @ Param figurenote */Public void interpretfigure (string figurenote) {system. out. println ("the image to be printed is:"); For (string linenote: figurenote. split ("\ s * [\ r \ n] \ s *") {interpretline (linenote, false );}} /*** explain the graphic markup of the given row * @ Param linenote graphic markup of the given row */Public void interpretline (string linenote, Boolean tipflag) {If (tipflag) {system. out. println ("Row flag:" + linenote);} matcher = line_pattern.matcher (L Inenote); If (! Matcher. Matches () {Throw new illegalargumentexception ("invalid graphic tag, please check! ");} Int linenum = 0; If (matcher. group (1) = NULL) {linenum = 1;} else {linenum = integer. parseint (matcher. group (2);} string lineinfo = matcher. group (3); For (INT I = 0; I <linenum; I ++) {printline (lineinfo); system. out. println () ;}}/*** print the row Tag Information Based on the given row tag information * @ Param lineinfo */Public void printline (string lineinfo) {If (lineinfo = NULL | lineinfo. equals ("") {return;} string partnote = ""; matcher = part_pattern.matcher (""); string flag = NULL; int num = 0; struct = new struct (lineinfo); While (struct. hasnext (part_pattern) {partnote = regular. next (); matcher. reset (partnote); If (matcher. matches () {num = integer. parseint (matcher. group (1); flag = matcher. group (2); If (flag. equals ("X") | flag. equals ("X") {printnchars ('x', num);} else {printnchars ('', num );}}}} /** print n symbols specified by Ch */private void printnchars (char CH, int N) {If (n <= 0) {return ;} while (n --> 0) {system. out. printf ("% C", CH );}}}
package patterns.interpretation;public class InterpreterTester {private static Interpreter ip = new Interpreter();public static void main(String[] args){testInterpretLine();printDiamond();printCharH();printCharC();}public static void printDiamond(){String figureNote = "2b 1x 2b \n 1b 1x 1b 1x 1b \n 1x 3b 1x \n 1b 1x 1b 1x 1b \n 2b 1x 2b \n";ip.interpretFigure(figureNote);}public static void printCharH(){String figureNote = "2l 1x 3b 1x \n 5x \n 2l 1x 3b 1x\n";ip.interpretFigure(figureNote);}public static void printCharC(){String figureNote = "1b 5x \n 3l 1x \n 1b 5x \n";ip.interpretFigure(figureNote);}public static void testInterpretLine(){String exString1 = "3l \n 3L \n 1l 4b \n 1l 3x \n 3l 2b 2x \n ";String exString2 = "3l 5b 2x 3b\n 3l 5x 3b 5x \n";String exString3 = "03l 23x 4b \n 3l 023x 43b \n 3l 23x 043b \n 5b \n 3x \n 5b 3x \n 3x 5b \n";String totalString = exString1 + exString2 + exString3;String[] multLines = totalString.split("\n");for (String line: multLines) {try { ip.interpretLine(line, true);} catch (Exception e) { System.out.println(e.getMessage());} }}}
Summary:
By introducing a set of concise notes and corresponding interpreters, we have improved the reusability of printed patterns. For any pattern to be printed, the desired pattern can be easily printed as long as the corresponding instruction is written following this method. In addition, this method is easy to understand for non-technical general users. This shows that the method and interpreter are indeed a different solution.