Writing this article originated from a programming track organized by the company. The final conclusion is to try to use the existing library to convert the problem into a problem that can be solved by existing library algorithms. Readability is the first, efficiency 2. What the old guys say is always confusing. Don't implement a function on your own. in order to extract a little bit of performance, it may not be able to squeeze it out in the end! I don't know if there are any special reasons. The code displayed by the last few bosses is exactly the same. Although the languages are different, it is like direct translation. Is Programming quite the same, what do the Elders know about "Tao "?
I also came up with the "standard practice", but I didn't use any libraries at all, and I couldn't solve the library at all. Although I had pseudo code, When I converted it into C code, I encountered an obstacle that could not be broken through, because I didn't know map or vector at all, let alone STL. Besides a little bit of C ++ syntax, nothing else... Sometimes, I think I am not a programmer, but a network administrator.
I have no skills to use, and I have no knowledge to use in libraries. I have to use standard C from scratch. Although the efficiency is not necessarily high, in terms of readability, I can only understand it myself. However, in any case, it is implemented, and all the time complexity is controllable, because the entire code has not fallen into any library-implemented algorithm black hole, for example, if you don't know how sort is implemented, the time complexity is uncontrollable.
The problem is: Sort string arrays according to the following rules
1. f must appear at the beginning;
2. l must appear at the end;
3. B must be in front of;
4. All identical strings must be put together.
In fact, the abstract point is that the input string is unordered, but the output must be ordered. The normal idea is to convert the rule key of the string into a number and then sort the numbers. However, to deal with the relationship between the string and the index, it is really troublesome to use the ADT in the library, therefore, in another way, the character string is divided into bits during scanning. The meaning of each bits is to locate its position based on the rule's priority order, binary Tree is an ideal choice.
Now the most important thing is to write a getprio function and a Compare function, which is easy to handle. The logic of the getprio function determines the final sorting result. This function can be complex or very simple. For example, in order to output strings that are not interest in the natural order, to meet the same requirements, you can save a container for the getprio function to save the PRIO values of all strings that are not interested in matching them.
The following is all the code:
# Include <stdio. h> # include <stdlib. h> # define Max 32 // a string linked list that stores the same PRIO string struct string_list {char * STR; struct string_list * Next ;}; // a string for packaging, carrying a priostruct string_wrap {char * string; int PRIO ;}; // binary tree that ultimately determines the string position struct string_node {struct string_list * string; struct string_list * last; int PRIO; struct string_node * left; struct string_node * right;}; // declare the function struct string_node * add_node (struct Str Ing_node *, struct string_wrap * STR, INT (* CMP) (struct string_wrap *, struct string_node *); void print_result (struct string_node *); // comparison function, comparison priority int normalcmp (struct string_wrap * N1, struct string_node * N2) {return N1-> prio-N2-> PRIO;} // getprio function, return the priority int getprio (char * s, int thread) {static int PRIO = 1; if (! Strcmp (S, "F") return 0; If (! Strcmp (S, "L") return 100; If (! Strcmp (S, "B") return 50; If (! Strcmp (S, "A") Return 51; // If You Want To output strings that do not want to be closed in the input order, release the following comments. // If only return PRIO ++, then the string will output // return PRIO ++ in the original order; // return the natural order, which is the same as the meaning of the preceding annotation: Return thread;} int main (INT argc, char ** argv) {struct string_node * root; int thread = 0; char string [Max]; char * STR [40] = {"L", "F ", "A", "dsfsfsg", "L", "B", "A", "SS", "a"}; root = NULL; int I = 0; while (STR [I]) {int PRIO = getprio (STR [I], ++ thread); struct string_wrap s W = {STR [I], PRIO}; root = add_node (root, & SW, normalcmp); I ++;} print_result (Root); Return 0 ;} // Insert the standard binary tree into struct string_node * add_node (struct string_node * P, struct string_wrap * New, INT (* CMP) (struct string_wrap * N1, struct string_node * N2 )) {int cmp_ret; If (P = NULL) {P = (struct string_node *) malloc (sizeof (struct string_node); P-> string = (struct string_list *) malloc (sizeof (struct string_li St); P-> string-> STR = (char *) calloc (1, strlen (New-> string); strcpy (p-> string-> STR, new-> string); P-> last = p-> string; P-> PRIO = new-> PRIO; P-> left = p-> right = NULL ;} else if (cmp_ret = CMP (new, p) = 0) {struct string_list * Next = (struct string_list *) calloc (1, sizeof (struct string_list )); next-> STR = (char *) calloc (1, strlen (New-> string); strcpy (next-> STR, new-> string ); p-> last-> next = N EXT;} else if (cmp_ret <0) {P-> left = add_node (p-> left, new, CMP );} else {P-> right = add_node (p-> right, new, CMP) ;}return P ;}// output the result. If printf is not used, you can use a container to install the result string void print_result (struct string_node * P) {If (P! = NULL) {print_result (p-> left); For (; P-> string = p-> string-> next) {printf ("% s \ n", p-> string-> Str);} print_result (p-> right );}}
Finally, we should sum up that we should not consider the time complexity when writing this type of algorithm. We should first implement it and then optimize it slowly. No matter how complicated it is, as long as the computing can be terminated, that is one idea. You need to use code to implement your own idea, and then think about another idea, instead of creating a lot of diagrams, a lot of pseudocode, and then compare and splice them, in the end, I spent a lot of effort to implement a four-way algorithm. People's ideas depend on their first impressions. As long as you can manually sort messy strings into rules, you must have your own ideas for doing so, the so-called algorithm is to write down this idea in the language of the program. Since you can use text to describe, why can't you use C or Java to describe it? Big O is a future issue. It is only an afterthought comment. When you have multiple plans, you should give a comment. If we use Big O as the benchmark at the beginning, so there will be no good results. First, we will do things, and then we will consider whether there is a better way, rather than starting from the beginning to think about how to do the best.
Another problem is related to O. If you use the STL container of C ++ to complete this algorithm, you must first know the time complexity of these container operations, then you can calculate the time complexity of your entire algorithm. Don't think the code is simple and efficient. You have used a lookup to complete a search operation. Suppose there is a lookup operation primitive in STL, I used 10 lines of C code to complete the same operation. Your readability is better than mine, and your efficiency may be better than mine. However, is 100% better than mine? Do you know the time complexity of the loopup primitive? This seems to return to the original problem:
Readability first, efficiency second, do not implement an operation on your own, in order to extract a bit of performance.
However, I do not quite agree with this point of view. As a kind of spirit, keeping improving is what every programmer, especially a hacker, pursues, such people especially want to put everything under their own control, that is, everything is controllable. the readability of the Code is only one aspect they are pursuing. If they are not working on projects, not for timely delivery, not for software engineering, so readability and "best use of libraries" become secondary. Every programmer who strives for perfection is far more than just the one in software engineering. They should regard implementation algorithms as a game. The following is an example.
Friends come from afar. There is a good restaurant opposite the community. It costs 300 yuan to get a good meal and drink. You only need to reserve a seat, pay for it, and then take your friends with you. Another choice is that you go to the supermarket to buy a few pounds of meat, some vegetables, some condiments and materials, buy another bottle of good wine, and then go home and cook it yourself. Wait for your friends to arrive. What is the total cost, it may be far more than 300 yuan. How do you choose? If we calculate the time cost and convenience, it is the best way to get out of the restaurant. Now we have always been advocating this. Isn't it all done like this? But if you want to find a sense of accomplishment and a kind of interest to your friends, not just to show your cooking skills, I believe you will choose your own, although it is very likely that, due to poor cooking skills, good materials will be ruined (I have experienced n times), but the meaning is different.
From the perspective of engineering, there is no need to cook for the social division of labor. However, from the perspective of life, there are still some kitchen utensils to be prepared at home. The minimum meaning is different. The programmer feels like this. Although there are so many libraries, so many frameworks can be used. However, if it is not for a project, it is better to implement a small idea by yourself, of course, those libraries and frameworks will also be used. After all, the programmer's work is for the company, and the company is completely considering the problem from the perspective of software engineering. Therefore, you should not always use libraries and existing implementations. You can do this in the project. It is not appropriate to do things or do some hack yourself.
I have heard from students who have come from the university that the university teacher taught me how to start programming. I must first learn the command line and then try IDE, but I have never been taught that way, even though, I agree with it very much. If you don't understand the principle and just splice a simple library, it's just a castle in the air. Such a person may be a good programmer, but it's hard to become a good designer, it is better not to contact them for emergency troubleshooting. My point of view is not to make everyone have to do it on their own. I don't have any pride in saying this. I just want to say: you know what it is, you know what it is, and you don't have to explain it. I don't want to explain it, but it's just a glimpse of it!