从c++到golang,golang中的对应C++的STL是哪些

2024-08-30 22:48:09 浏览数 (2)

从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 : vec.push_back(4);
    • Go: slice = append(slice, 4)
  • 访问元素
    • C : int first = vec[0];
    • Go: first := slice[0]
  • 修改元素
    • C : vec[0] = 10;
    • Go: slice[0] = 10
  • 删除元素
    • C : vec.pop_back();vec.erase(vec.begin() index);
    • Go: 删除操作不是直接的,可以通过切片语法实现:slice = slice[:index]slice = slice[index 1:]
  • 获取大小
    • C : size_t size = vec.size();
    • Go: size := len(slice)
  • 清空容器
    • C : vec.clear();
    • Go: slice = slice[:0]
  • 遍历元素
    • C : 使用范围基循环 for(auto& x : vec) { ... }
    • Go: 使用range进行遍历 for _, value := range slice { ... }

字符串处理: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 : str = " World!";
    • Go: str = " World!"
  • 访问字符
    • C : char ch = str[0];
    • Go: ch := str[0]
  • 修改字符
    • C : str[0] = 'h';
    • Go: Go的字符串不可变,无法直接修改字符。
  • 获取字符串长度
    • C : size_t length = str.length();
    • Go: length := len(str)
  • 查找子字符串
    • C : size_t pos = str.find("World");
    • Go: pos := strings.Index(str, "World")
  • 替换子字符串
    • C : str.replace(5, 5, "there");
    • Go: str = strings.Replace(str, "World", "there", 1)
  • 截取子字符串
    • C : std::string sub = str.substr(7, 5);
    • Go: sub := str[7:12]
  • 比较字符串
    • C : bool result = (str == "Hello, World!");
    • Go: result := str == "Hello, World!"
  • 转换为小写/大写
    • C : str = str;
      • 需要使用额外的库函数,如std::transform(str.begin(), str.end(), str.begin(), ::tolower);
    • Go: str = strings.ToLower(str)
  • 去除空白字符
    • C : str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
    • Go: str = strings.TrimSpace(str)
  • 分割字符串
    • C : 需要手动实现或使用std::istringstream
    • Go: tokens := strings.Split(str, " ")

映射:Map

在C 和Go中,映射(Map)是一种将键(Key)映射到值(Value)的数据结构。C 提供了两种类型的映射:std::mapstd::unordered_mapstd::map是基于红黑树实现的有序映射,而std::unordered_map是基于哈希表实现的无序映射。Go中的映射(Map)也是基于哈希表实现的,元素无序,但提供了简洁的操作方式。

方法对比

构造和初始化
  • C :
代码语言:cpp复制
std::map<int, std::string> map = {{1, "one"}, {2, "two"}};
std::unordered_map<int, std::string> unorderedMap = {{1, "one"}, {2, "two"}};
  • Go:
代码语言:go复制
  mapIntStr := map[int]string{1: "one", 2: "two"}
添加元素
  • C :
代码语言:cpp复制
  map[3] = "three"; // 对于std::map和std::unordered_map
  • Go:
代码语言:go复制
mapIntStr[3] = "three"
访问元素
  • C :
代码语言:cpp复制
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:
代码语言:go复制
  value, ok := mapIntStr[1] // 访问存在的键,ok用于判断键是否存在
修改元素
  • C :
代码语言:cpp复制
  map[1] = "ONE"; // 修改存在的键
  • Go:
代码语言:go复制
  mapIntStr[1] = "ONE"
删除元素
  • C :
代码语言:cpp复制
  map.erase(1); // 删除键为1的元素
  unorderedMap.erase(1);
  • Go:
代码语言:go复制
  delete(mapIntStr, 1)
检查元素是否存在
  • C :
代码语言:cpp复制
  bool exists = map.count(1) > 0; // std::map和std::unordered_map
  • Go:
代码语言:go复制
  _, exists := mapIntStr[1]
获取所有值
  • C :
代码语言:cpp复制
  for (const auto& pair : map) {
      std::cout << pair.second << std::endl;
  }
  • Go:
代码语言:go复制
  for _, value := range mapIntStr {
      fmt.Println(value)
  }
获取映射的大小
  • C :
代码语言:cpp复制
  size_t size = map.size(); // std::map和std::unordered_map
  • Go:
代码语言:go复制
size := len(mapIntStr)
清空映射
  • C :
代码语言:cpp复制
  map.clear(); // std::map和std::unordered_map
  • Go:
代码语言:go复制
  mapIntStr = make(map[int]string)

对比分析

  • C :
    • std::mapstd::unordered_map提供了丰富的成员函数来操作映射。
    • std::map保持元素的有序性,而std::unordered_map提供更快的查找速度但元素无序。
    • 访问不存在的键时,std::mapstd::unordered_map会抛出异常。
    • 访问不存在的键时,使用[]操作符会插入一个具有默认值的新元素,而使用at()成员函数则会抛出std::out_of_range异常。
  • Go:
    • Go的映射是无序的,并且每次访问不存在的键时会返回零值和ok标志,而不是抛出异常。
    • Go的映射操作通常更简洁,内置了更多的处理函数。

集合

在C 中,std::setstd::unordered_set提供了有序和无序的集合功能。Go语言没有内置的集合类型,但可以通过映射(Map)来模拟集合的行为,通过将元素作为键,而值可以是布尔类型或其他占位类型。

C 中的std::setstd::unordered_set

  • 构造和初始化
    • C : std::set<int> set = {1, 2, 3};
代码语言:cpp复制
    std::set<int> set = {1, 2, 3};
  • 添加元素
    • C : set.insert(4);
代码语言:cpp复制
    set.insert(4);
  • 访问元素
    • C : bool exists = set.find(2) != set.end();
代码语言:cpp复制
    bool exists = set.find(2) != set.end();
  • 删除元素
    • C : set.erase(2);
代码语言:cpp复制
    set.erase(2);
  • 检查元素是否存在
  • C : bool exists = set.count(2) > 0;
代码语言:cpp复制
    bool exists = set.count(2) > 0;
  • 获取集合大小
    • C : size_t size = set.size();
代码语言:cpp复制
    size_t size = set.size();
  • 清空集合
    • C : set.clear();
代码语言:cpp复制
    set.clear();
  • 遍历集合
    • C : 使用范围基循环 for (int num : set) { ... }
代码语言:cpp复制
    for (int num : set) {
        std::cout << num << " ";
    }

Go中模拟的Set

  • 构造和初始化
  • Go: set := make(map[int]struct{})
代码语言:go复制
    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)
代码语言:go复制
    size := len(set)
  • 清空集合
  • Go: set = make(map[int]struct{})
代码语言:go复制
    set = make(map[int]struct{})
  • 遍历集合
    • Go: 使用range进行遍历
代码语言:go复制
    for num := range set {
        fmt.Println(num)
    }

对比分析

  • C :
    • std::setstd::unordered_set提供了丰富的成员函数来操作集合。
    • std::set保持元素的有序性,而std::unordered_set提供更快的查找速度但元素无序。
    • 访问不存在的键时,std::setstd::unordered_set会返回一个迭代器到集合的末尾。
  • Go:
    • Go的映射是无序的,并且每次访问不存在的键时会返回零值和ok标志,而不是返回一个迭代器。
    • Go的映射操作通常更简洁,内置了更多的处理函数。

栈和队列

C 提供了std::stackstd::queue等容器适配器,而Go可以通过切片或通道来模拟这些数据结构。以下是C 和Go中栈和队列操作的详细对比:

C 中的std::stack

  • 构造和初始化
    • C : std::stack<int> stack;
  • 添加元素(压栈)
    • C : stack.push(1);
  • 访问顶部元素
    • C : int top = stack.top();
  • 删除顶部元素(弹栈)
    • C : stack.pop();
  • 检查栈是否为空
    • C : bool empty = stack.empty();
  • 获取栈的大小
    • C : size_t size = stack.size();

Go中模拟的Stack

  • 构造和初始化
    • Go: stack := []int{}stack = append(stack, 1)
  • 添加元素(压栈)
    • Go: stack = append(stack, value)stack = append(stack, 1)
  • 访问顶部元素
    • Go: top := stack[len(stack)-1]top := stack[len(stack)-1]
  • 删除顶部元素(弹栈)
    • Go: stack = stack[:len(stack)-1]stack = stack[:len(stack)-1]
  • 检查栈是否为空
    • Go: empty := len(stack) == 0empty := len(stack) == 0
  • 获取栈的大小
    • Go: size := len(stack)size := len(stack)

C 中的std::queue

  • 构造和初始化
    • C : std::queue<int> queue;
  • 添加元素(入队)
    • C : queue.push(1);
  • 访问前端元素
    • C : int front = queue.front();
  • 删除前端元素(出队)
    • C : queue.pop();
  • 检查队列是否为空
    • C : bool empty = queue.empty();
  • 获取队列的大小
    • C : size_t size = queue.size();

Go中模拟的Queue

  • 构造和初始化
    • Go: queue := []int{}queue = append(queue, 1)
  • 添加元素(入队)
    • Go: queue = append(queue, value)queue = append(queue, 1)
  • 访问前端元素
    • Go: front := queue[0]front := queue[0]
  • 删除前端元素(出队)
    • Go: queue = queue[1:]queue = queue[1:]
  • 检查队列是否为空
    • Go: empty := len(queue) == 0empty := len(queue) == 0
  • 获取队列的大小
    • Go: size := len(queue)size := len(queue)

C 中的std::deque

  • 构造和初始化
    • C : std::deque<int> deque;
  • 添加元素到末尾(push back)
    • C : deque.push_back(1);
  • 添加元素到前端(push front)
    • C : deque.push_front(0);
  • 删除元素从末尾(pop back)
    • C : deque.pop_back();
  • 删除元素从前端(pop front)
    • C : deque.pop_front();
  • 检查双端队列是否为空
    • C : bool empty = deque.empty();
  • 获取双端队列的大小
    • C : size_t size = deque.size();

Go中模拟的Deque

  • 构造和初始化
    • Go: deque := []int{}deque = append(deque, 1) // push back
  • 添加元素到末尾(push back)
    • Go: deque = append(deque, value)deque = append(deque, 1)
  • 添加元素到前端(push front)
    • Go: 需要更多的操作,例如先插入到切片的开始位置deque = append([]int{value}, deque...)
  • 删除元素从末尾(pop back)
    • Go: deque = deque[:len(deque)-1]deque = deque[:len(deque)-1]
  • 删除元素从前端(pop front)
    • Go: deque = deque[1:]deque = deque[1:]
  • 检查双端队列是否为空
    • Go: empty := len(deque) == 0empty := len(deque) == 0
  • 获取双端队列的大小
    • Go: size := len(deque)size := len(deque)
go

0 人点赞