目录:
1. 泛型,cpp template,go
2. 反射(还在写)
3. 其他[http://链接等下贴],作为Directory目录检索--pytorch-d2l, c++ pointer和内存地址
泛型generics
产生之初是为了替代基类Base Type,避免格式转化。
泛泛而谈的类型。general datatype既视感
反射Reflect
Go里面很多地方可以用反射,比如最常见fmt就用了反射判断该输出的类型是啥
fmt.Println,不过有些直接用case switch实现不用反射
func Println(a ...any) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
func Fprintln(w io.Writer, a ...any) (n int, err error) {
p := newPrinter()
p.doPrintln(a)
n, err = w.Write(p.buf)
p.free()
return
}
func (p *pp) doPrintln(a []any) {
for argNum, arg := range a {
if argNum > 0 {
p.buf.writeByte(' ')
}
p.printArg(arg, 'v')
}
p.buf.writeByte('\n')
}
func (p *pp) printArg(arg any, verb rune) {
p.arg = arg
p.value = reflect.Value{}
if arg == nil {
switch verb {
case 'T', 'v':
p.fmt.padString(nilAngleString)
default:
p.badVerb(verb)
}
return
}
// Special processing considerations.
// %T (the value's type) and %p (its address) are special; we always do them first.
switch verb {
case 'T':
p.fmt.fmtS(reflect.TypeOf(arg).String())
return
case 'p':
p.fmtPointer(reflect.ValueOf(arg), 'p')
return
}
// 一些数据类型比如布尔,浮点,整数,字符串,字节可以字节输出无需反射 Some types can be done without reflection.
switch f := arg.(type) {
case bool:
p.fmtBool(f, verb)
case float32:
p.fmtFloat(float64(f), 32, verb)
case float64:
p.fmtFloat(f, 64, verb)
case complex64:
p.fmtComplex(complex128(f), 64, verb)
case complex128:
p.fmtComplex(f, 128, verb)
case int:
p.fmtInteger(uint64(f), signed, verb)
case int8:
p.fmtInteger(uint64(f), signed, verb)
case int16:
p.fmtInteger(uint64(f), signed, verb)
case int32:
p.fmtInteger(uint64(f), signed, verb)
case int64:
p.fmtInteger(uint64(f), signed, verb)
case uint:
p.fmtInteger(uint64(f), unsigned, verb)
case uint8:
p.fmtInteger(uint64(f), unsigned, verb)
case uint16:
p.fmtInteger(uint64(f), unsigned, verb)
case uint32:
p.fmtInteger(uint64(f), unsigned, verb)
case uint64:
p.fmtInteger(f, unsigned, verb)
case uintptr:
p.fmtInteger(uint64(f), unsigned, verb)
case string:
p.fmtString(f, verb)
case []byte:
p.fmtBytes(f, verb, "[]byte")
// 如果上面这一大堆都不是,那就只能反射去取值了。
case reflect.Value:
// Handle extractable values with special methods
// since printValue does not handle them at depth 0.
if f.IsValid() && f.CanInterface() {
p.arg = f.Interface()
if p.handleMethods(verb) {
return
}
}
p.printValue(f, verb, 0)
default:
// If the type is not simple, it might have methods.
if !p.handleMethods(verb) {
// Need to use reflection, since the type had no
// interface methods that could be used for formatting.
p.printValue(reflect.ValueOf(f), verb, 0)
}
}
}
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string `json:"name" validate:"required"`
Age int `json:"age" validate:"min=0"`
}
func main() {
person := Person{Name: "Alice", Age: 30}
t := reflect.TypeOf(person)
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
jsonTag := field.Tag.Get("json")
validateTag := field.Tag.Get("validate")
fmt.Printf("Field: %s, JSON Tag: %s, Validate Tag: %s\n", field.Name, jsonTag, validateTag)
}
}
cpp:
cpp里template可以实现泛型,挺多人写题时模板里用。不用考虑类型了,直接声明为T,啥类型都能搞。
1. 快排 (分治,分一半,不断细分)
#include <iostream>
#include <vector>
#include <functional>
template <typename T>
int partition(std::vector<T>& arr, int low, int high, std::function<bool(T, T)> comp) {
T pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (comp(arr[j], pivot)) {
i++;
std::swap(arr[i], arr[j]);
}
}
std::swap(arr[i + 1], arr[high]);
return (i + 1);
}
template <typename T>
void quickSort(std::vector<T>& arr, int low, int high, std::function<bool(T, T)> comp) {
if (low < high) {
int pi = partition(arr, low, high, comp);
quickSort(arr, low, pi - 1, comp);
quickSort(arr, pi + 1, high, comp);
}
}
int main() {
std::vector<int> arr = {10, 7, 8, 9, 1, 5};
quickSort(arr, 0, arr.size() - 1, [](int a, int b) { return a < b; });
for (int i : arr) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
//DFS
#include <iostream>
#include <vector>
#include <stack>
#include <functional>
template <typename T>
void dfs(T start, std::function<void(T)> visit, std::function<std::vector<T>(T)> getNeighbors) {
std::stack<T> stack;
stack.push(start);
while (!stack.empty()) {
T node = stack.top();
stack.pop();
visit(node);
for (T neighbor : getNeighbors(node)) {
stack.push(neighbor);
}
}
}
int main() {
std::vector<std::vector<int>> graph = {
{1, 2},
{0, 3, 4},
{0, 4},
{1, 5},
{1, 2, 5},
{3, 4}
};
dfs(0, [](int node) { std::cout << node << " "; }, [&](int node) { return graph[node]; });
return 0;
}
//BFS queue队列
#include <iostream>
#include <vector>
#include <queue>
#include <functional>
template <typename T>
void bfs(T start, std::function<void(T)> visit, std::function<std::vector<T>(T)> getNeighbors) {
std::queue<T> queue;
queue.push(start);
while (!queue.empty()) {
T node = queue.front();
queue.pop();
visit(node);
for (T neighbor : getNeighbors(node)) {
queue.push(neighbor);
}
}
}
int main() {
std::vector<std::vector<int>> graph = {
{1, 2},
{0, 3, 4},
{0, 4},
{1, 5},
{1, 2, 5},
{3, 4}
};
bfs(0, [](int node) { std::cout << node << " "; }, [&](int node) { return graph[node]; });
return 0;
}
//为int类型特定写个实现
template <>
int fibonacci<int>(int n) {
// Specialized implementation for int
if (n <= 1) return n;
int a = 0, b = 1, c;
for (int i = 2; i <= n; ++i) {
c = a + b;
a = b;
b = c;
}
return c;
}
//多个类型
template <typename T1, typename T2>
auto add(T1 a, T2 b) -> decltype(a + b) {
return a + b;
}
int main() {
std::cout << add(5, 3.2) << std::endl; // Works with int and double
return 0;
}
Go的泛型
package main
import "fmt"
func fibonacci[T int | int64](n T) T { //| float64不能加浮点,下面dp的slice切片只接受非负整数
dp := make([]T, n+1)
dp[0] = 0
dp[1] = 1
for i := T(2); i <= n; i++ {
dp[i] = dp[i-1] + dp[i-2]
}
return dp[n]
}
func main() {
n := 10
fmt.Printf("Fibonacci(%d) = %d\n", n, fibonacci(n))
}