从c 到golang,golang中的对应C 的STL是哪些
动态数组:Vector与Slice
C 的std::vector
是一个序列容器,它封装了动态大小数组的行为。
Go的切片(Slice)是动态的,基于数组,但提供了更灵活的接口。
方法对比
C 中的std::vector
代码语言:c复制std::vector<int> vec = {1, 2, 3};
vec.push_back(4);
Go中的Slice
代码语言:c复制slice := []int{1, 2, 3}
slice = append(slice, 4)
- 构造和初始化
- C :
std::vector<int> vec = {1, 2, 3};
- Go:
slice := []int{1, 2, 3}
- C :
- 添加元素
- C :
vec.push_back(4);
- Go:
slice = append(slice, 4)
- C :
- 访问元素
- C :
int first = vec[0];
- Go:
first := slice[0]
- C :
- 修改元素
- C :
vec[0] = 10;
- Go:
slice[0] = 10
- C :
- 删除元素
- C :
vec.pop_back();
或vec.erase(vec.begin() index);
- Go: 删除操作不是直接的,可以通过切片语法实现:
slice = slice[:index]
或slice = slice[index 1:]
- C :
- 获取大小
- C :
size_t size = vec.size();
- Go:
size := len(slice)
- C :
- 清空容器
- C :
vec.clear();
- Go:
slice = slice[:0]
- C :
- 遍历元素
- C : 使用范围基循环
for(auto& x : vec) { ... }
- Go: 使用
range
进行遍历for _, value := range slice { ... }
- C : 使用范围基循环
字符串处理:String
C 中的std::string
是一个可变的数据结构,用于处理文本数据。Go中的字符串是不可变的,但Go提供了丰富的字符串处理函数。
方法对比
C 中的`std::string
代码语言:cpp复制std::string str = "Hello, ";
str = " World!";
Go中的String
代码语言:go复制str := "Hello, "
str = " World!"
- 构造和初始化
- C :
std::string str = "Hello, World!";
- Go:
str := "Hello, World!"
- C :
- 拼接字符串
- C :
str = " World!";
- Go:
str = " World!"
- C :
- 访问字符
- C :
char ch = str[0];
- Go:
ch := str[0]
- C :
- 修改字符
- C :
str[0] = 'h';
- Go: Go的字符串不可变,无法直接修改字符。
- C :
- 获取字符串长度
- C :
size_t length = str.length();
- Go:
length := len(str)
- C :
- 查找子字符串
- C :
size_t pos = str.find("World");
- Go:
pos := strings.Index(str, "World")
- C :
- 替换子字符串
- C :
str.replace(5, 5, "there");
- Go:
str = strings.Replace(str, "World", "there", 1)
- C :
- 截取子字符串
- C :
std::string sub = str.substr(7, 5);
- Go:
sub := str[7:12]
- C :
- 比较字符串
- C :
bool result = (str == "Hello, World!");
- Go:
result := str == "Hello, World!"
- C :
- 转换为小写/大写
- C :
str = str;
- 需要使用额外的库函数,如
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
- 需要使用额外的库函数,如
- Go:
str = strings.ToLower(str)
- C :
- 去除空白字符
- C :
str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
- Go:
str = strings.TrimSpace(str)
- C :
- 分割字符串
- C : 需要手动实现或使用
std::istringstream
- Go:
tokens := strings.Split(str, " ")
- C : 需要手动实现或使用
映射:Map
在C 和Go中,映射(Map)是一种将键(Key)映射到值(Value)的数据结构。C 提供了两种类型的映射:std::map
和std::unordered_map
。std::map
是基于红黑树实现的有序映射,而std::unordered_map
是基于哈希表实现的无序映射。Go中的映射(Map)也是基于哈希表实现的,元素无序,但提供了简洁的操作方式。
方法对比
构造和初始化
- C :
std::map<int, std::string> map = {{1, "one"}, {2, "two"}};
std::unordered_map<int, std::string> unorderedMap = {{1, "one"}, {2, "two"}};
- Go:
mapIntStr := map[int]string{1: "one", 2: "two"}
添加元素
- C :
map[3] = "three"; // 对于std::map和std::unordered_map
- Go:
mapIntStr[3] = "three"
访问元素
- C :
std::string value = map[1]; // 访问存在的键
// 如果键不存在,使用[]运算符会插入一个默认值
std::string defaultValue = map[3]; // 键3不存在,将插入默认值空字符串""
// 使用at()访问不存在的键会抛出异常
try {
std::string atValue = map.at(3); // 将抛出异常
} catch (const std::out_of_range& e) {
std::cerr << e.what() << 'n';
}
- Go:
value, ok := mapIntStr[1] // 访问存在的键,ok用于判断键是否存在
修改元素
- C :
map[1] = "ONE"; // 修改存在的键
- Go:
mapIntStr[1] = "ONE"
删除元素
- C :
map.erase(1); // 删除键为1的元素
unorderedMap.erase(1);
- Go:
delete(mapIntStr, 1)
检查元素是否存在
- C :
bool exists = map.count(1) > 0; // std::map和std::unordered_map
- Go:
_, exists := mapIntStr[1]
获取所有值
- C :
for (const auto& pair : map) {
std::cout << pair.second << std::endl;
}
- Go:
for _, value := range mapIntStr {
fmt.Println(value)
}
获取映射的大小
- C :
size_t size = map.size(); // std::map和std::unordered_map
- Go:
size := len(mapIntStr)
清空映射
- C :
map.clear(); // std::map和std::unordered_map
- Go:
mapIntStr = make(map[int]string)
对比分析
- C :
std::map
和std::unordered_map
提供了丰富的成员函数来操作映射。std::map
保持元素的有序性,而std::unordered_map
提供更快的查找速度但元素无序。- 访问不存在的键时,
std::map
和std::unordered_map
会抛出异常。 - 访问不存在的键时,使用
[]
操作符会插入一个具有默认值的新元素,而使用at()
成员函数则会抛出std::out_of_range
异常。
- Go:
- Go的映射是无序的,并且每次访问不存在的键时会返回零值和
ok
标志,而不是抛出异常。 - Go的映射操作通常更简洁,内置了更多的处理函数。
- Go的映射是无序的,并且每次访问不存在的键时会返回零值和
集合
在C 中,std::set
和std::unordered_set
提供了有序和无序的集合功能。Go语言没有内置的集合类型,但可以通过映射(Map)来模拟集合的行为,通过将元素作为键,而值可以是布尔类型或其他占位类型。
C 中的std::set
和std::unordered_set
- 构造和初始化
- C :
std::set<int> set = {1, 2, 3};
- C :
std::set<int> set = {1, 2, 3};
- 添加元素
- C :
set.insert(4);
- C :
set.insert(4);
- 访问元素
- C :
bool exists = set.find(2) != set.end();
- C :
bool exists = set.find(2) != set.end();
- 删除元素
- C :
set.erase(2);
- C :
set.erase(2);
- 检查元素是否存在
- C :
bool exists = set.count(2) > 0;
bool exists = set.count(2) > 0;
- 获取集合大小
- C :
size_t size = set.size();
- C :
size_t size = set.size();
- 清空集合
- C :
set.clear();
- C :
set.clear();
- 遍历集合
- C : 使用范围基循环
for (int num : set) { ... }
- C : 使用范围基循环
for (int num : set) {
std::cout << num << " ";
}
Go中模拟的Set
- 构造和初始化
- Go:
set := make(map[int]struct{})
set := make(map[int]struct{})
set[1] = struct{}{}
set[2] = struct{}{}
set[3] = struct{}{}
- 添加元素
- Go:
set[key] = struct{}{}
- Go:
set[4] = struct{}{}
- 访问元素
- Go:
_, exists := set[key]; exists
- Go:
_, exists := set[2]; exists
- 删除元素
- Go:
delete(set, key)
- Go:
delete(set, 2)
- 检查元素是否存在
- Go:
_, exists := set[key]; exists
- Go:
_, exists := set[2]; exists
- 获取集合大小
- Go:
size := len(set)
size := len(set)
- 清空集合
- Go:
set = make(map[int]struct{})
set = make(map[int]struct{})
- 遍历集合
- Go: 使用
range
进行遍历
- Go: 使用
for num := range set {
fmt.Println(num)
}
对比分析
- C :
std::set
和std::unordered_set
提供了丰富的成员函数来操作集合。std::set
保持元素的有序性,而std::unordered_set
提供更快的查找速度但元素无序。- 访问不存在的键时,
std::set
和std::unordered_set
会返回一个迭代器到集合的末尾。
- Go:
- Go的映射是无序的,并且每次访问不存在的键时会返回零值和
ok
标志,而不是返回一个迭代器。 - Go的映射操作通常更简洁,内置了更多的处理函数。
- Go的映射是无序的,并且每次访问不存在的键时会返回零值和
栈和队列
C 提供了std::stack
和std::queue
等容器适配器,而Go可以通过切片或通道来模拟这些数据结构。以下是C 和Go中栈和队列操作的详细对比:
C 中的std::stack
- 构造和初始化
- C :
std::stack<int> stack;
- C :
- 添加元素(压栈)
- C :
stack.push(1);
- C :
- 访问顶部元素
- C :
int top = stack.top();
- C :
- 删除顶部元素(弹栈)
- C :
stack.pop();
- C :
- 检查栈是否为空
- C :
bool empty = stack.empty();
- C :
- 获取栈的大小
- C :
size_t size = stack.size();
- C :
Go中模拟的Stack
- 构造和初始化
- Go:
stack := []int{}
stack = append(stack, 1)
- Go:
- 添加元素(压栈)
- Go:
stack = append(stack, value)
stack = append(stack, 1)
- Go:
- 访问顶部元素
- Go:
top := stack[len(stack)-1]
top := stack[len(stack)-1]
- Go:
- 删除顶部元素(弹栈)
- Go:
stack = stack[:len(stack)-1]
stack = stack[:len(stack)-1]
- Go:
- 检查栈是否为空
- Go:
empty := len(stack) == 0
empty := len(stack) == 0
- Go:
- 获取栈的大小
- Go:
size := len(stack)
size := len(stack)
- Go:
C 中的std::queue
- 构造和初始化
- C :
std::queue<int> queue;
- C :
- 添加元素(入队)
- C :
queue.push(1);
- C :
- 访问前端元素
- C :
int front = queue.front();
- C :
- 删除前端元素(出队)
- C :
queue.pop();
- C :
- 检查队列是否为空
- C :
bool empty = queue.empty();
- C :
- 获取队列的大小
- C :
size_t size = queue.size();
- C :
Go中模拟的Queue
- 构造和初始化
- Go:
queue := []int{}
queue = append(queue, 1)
- Go:
- 添加元素(入队)
- Go:
queue = append(queue, value)
queue = append(queue, 1)
- Go:
- 访问前端元素
- Go:
front := queue[0]
front := queue[0]
- Go:
- 删除前端元素(出队)
- Go:
queue = queue[1:]
queue = queue[1:]
- Go:
- 检查队列是否为空
- Go:
empty := len(queue) == 0
empty := len(queue) == 0
- Go:
- 获取队列的大小
- Go:
size := len(queue)
size := len(queue)
- Go:
C 中的std::deque
- 构造和初始化
- C :
std::deque<int> deque;
- C :
- 添加元素到末尾(push back)
- C :
deque.push_back(1);
- C :
- 添加元素到前端(push front)
- C :
deque.push_front(0);
- C :
- 删除元素从末尾(pop back)
- C :
deque.pop_back();
- C :
- 删除元素从前端(pop front)
- C :
deque.pop_front();
- C :
- 检查双端队列是否为空
- C :
bool empty = deque.empty();
- C :
- 获取双端队列的大小
- C :
size_t size = deque.size();
- C :
Go中模拟的Deque
- 构造和初始化
- Go:
deque := []int{}
deque = append(deque, 1) // push back
- Go:
- 添加元素到末尾(push back)
- Go:
deque = append(deque, value)
deque = append(deque, 1)
- Go:
- 添加元素到前端(push front)
- Go: 需要更多的操作,例如先插入到切片的开始位置deque = append([]int{value}, deque...)
- 删除元素从末尾(pop back)
- Go:
deque = deque[:len(deque)-1]
deque = deque[:len(deque)-1]
- Go:
- 删除元素从前端(pop front)
- Go:
deque = deque[1:]
deque = deque[1:]
- Go:
- 检查双端队列是否为空
- Go:
empty := len(deque) == 0
empty := len(deque) == 0
- Go:
- 获取双端队列的大小
- Go:
size := len(deque)
size := len(deque)
- Go: