Will Arts Week 2 | leetcode 31 | go support value methods and pointer methods in generics | go

Time:2021-4-30

ARTS

Arts is an activity launched by Chen Hao in the geek time column. The purpose is to keep learning through sharing.

Each person writes an arts every week: algorithm is an algorithm problem, review is to read an English article, technology / tips is to share a small technology, share is to share a viewpoint.

Content of this week

You’ll see this week’s arts

  1. A seemingly permutation question is actually an intelligence question
  2. How can go try to provide new generic features while maintaining the original flavor.
  3. When we talk about whether the receiver of a method in go is a value type or a pointer type, we are actually talking about something.
  4. English is probably the only skill that most people have learned for more than ten years but never really used.

Algorithm

Don’t talk too much nonsense. Let’s look at the topic directly.

31. Next Permutation

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place and use only constant extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

It seems that permutation is mentioned in the title. It’s easy to start with the usual implementation of permutation, such as backtracking. But the title requires that the original array must be adjusted in place, and adjusted to the “next” value in dictionary order.

There are two prerequisites for making this topic.

  1. For a number, the “lexicographic order” of all the elements is actually the size of the number when the numbers in the array are arranged together. This conclusion you can use a few numbers disordered order to try, you will find the conclusion.
  2. After the conclusion of 1, it can be equivalent to finding the “smallest” number in the number larger than the current arrangement.

Based on the above two conclusions, the following solution can be derived slowly.

1. Find the first adjacent ascending element pair (I, J) from the back to the front to meet a [i] < a [J]. Then [J, end] must be in descending order
2. Find the first k satisfying a [i] < a [k] from back to front in [J, end]. A [i] and a [k] are respectively the "decimal" and "large number" mentioned above
3. Exchange a [i] with a [k]
4. It can be concluded that [J, end] must be in descending order and reverse [J, end] to make it in ascending order
5. If no matching adjacent element pair is found in step 1, it means that the current [begin, end] is in a descending order, then skip to step 4 directly

This problem does not use the same solution, and there are some restrictions on the solution, which is one of the reasons why I think this problem is more like an intelligence problem. The second reason is that I didn’t think of a good solution at all. The above solution comes from the solution of this problem in China.

I won’t post the code.

Review

This week’s article reviews the speech by Ian lance Taylor, an official member of go, on gophercon 2019 that go will support generics: why generics?

This article mainly introduces the go official thinking about whether to add generics to go, and the preliminary results, including some simple code examples.

Generally speaking, go officials are ready to provide generic features, but what speakers want to express more is go officials’ attitude towards generics than providing new features

  1. To minimize new concepts, officials don’t want to introduce too many new keywords because of generics.
  2. The complexity of generic code is borne by the writer, not the user. That is to say, we hope that users will spend less energy on generics when calling Generic packages. This part of the work should be done by providing functions.
  3. The generation time is short and the running speed is fast.
  4. Keep go clear and simple.

A thousand words come together into one sentence:

generics can bring a significant benefit to the language, but they are only worth doing if Go still feels like Go.

You can have the generic you want, but you can’t lose the flavor of go.

However, we have to say that generics, which are still in the draft stage, are really simple and clear. Finally, attach the original address, if you are interested, you can go and have a look.

Tip

This week’s technical details are about golang’s value / pointer receiver.

Let’s look at this problem first

This is a very classic question, the question of the main question is to sum up

  1. Golang is different in receiver (here refers to pointer and value) but has the same method name. How to judge whether an object implements an interface?
  2. What actually happens when the pointer receiver calls the value method that does not display the implementation?

First, post some information:

Effective go’s explanation of “pointer” or “value revealer” on the official website

Why do T and *T have different method sets? Also from the official website.

Should I define methods on values or pointers?

In fact, receiver is a grammatical sugar of go, which is very similar to ordinary formal parameters in function, except that go can help you get the address or dereference of actual parameters.

As for the “generate” method mentioned by the question owner, my understanding is that go will not “automatically generate” a new method for you. Instead, it will make some decisions when judging whether it can be used as the implementation of an interface or as the caller of a method. The types in go have different method sets for pointer receiver and value receiver. Specifically, in general, value receiver can only call level method, while pointer receiver can call all methods (including level method and value method). When you call the specified method through different receivers, go will do some “adaptation” for you. For example, when you call the pointer method with a value type caller that can get the address, it will help you get the address, or when you call the value method with a value type caller that can get the address, it will help you dereference.

Back to the question above, when running the following code.

var a Integer = 1
var b LessAdder = &a
b.Add(100)
fmt.Println(a)

b.Add(100)It’s actually to help you understand the quotation(*b).Add(100)But it’s still misleading to write like this. According to the official website, receiver is equivalent toAddFor the originalAdd

func (a Integer) Add(b Integer) {
    a += b
}

It can be equivalent to the following function.

void Add(a, b Integer) {
    a += b
}

In the parameter table aboveaWe continue our previous conjectureb.Add(100)It’s actually to help you understand the quotation(*b).Add(100).

And the real calling method should be like thisAdd(*b,100)So yes*bA copy of plus 100 does not changeaThe value of.

Another problem closely related to this problem is whether the object in go can be addressed. You can see the answer to this question.

remaining problems

Finally, there are still some incomprehensible aspects to this problem. For example, when will golang judge whether a value type caller uses the pointer method, and when will it judge whether a value type caller can get an address? Or is it possible to judge at the same time?

Share

This week’s flash.

In the past two years, I have found that I am very resistant to reading English documents. As long as there is a translation, I will go back to see the translation. If I really can’t find a translation, I may even go back to find a similar substitute in the Chinese world. In the long run, my English reading ability has been greatly reduced. In turn, I don’t want to read English documents.

During this period of time, when I was looking at the documents on the go official website, I suddenly didn’t want to endure this state any more and decided not to read the translation. After a few days, I feel that I have received a lot of goods. After all, these are first-hand materials. When reading English technical documents, there is no doubt about the correctness of the content (here refers to the go official website), and there is no need to judge the correctness of the content while reading. After going through the initial difficult stage, I feel more relaxed. Of course, the English world certainly has some misleading conclusions, but when it comes to official documents or foreign open source projects, English documents should be your first choice.