算法学习日记:运算符重载、字符串函数、中缀表达式求解、并查集、哈希表……

71 阅读5分钟

算法学习日记3

2023.5

面向对象C++ : 运算符重载

1.运算符重载

(1)n定义重载运算符和定义普通函数类似,只是该函数的名字是operator@,@表示要重载的运算符。

MinInt operator-()const{  //一元运算"-" 
  cout<<"MinInt::operator-"<<endl; 
  return MinInt(-b); 
} 
//定义MinInt类的一元运算‘-’

C++ map

Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,是有序键值对容器,元素的键是唯一的。

2023.9

字符串函数

 //string的析造函数
    string str1;               //生成空字符串
    string str2("123456789");  //生成"1234456789"的复制品
    string str3("12345", 0, 3);//结果为"123"
    string str4("0123456", 5);  //结果为"01234"
    string str5(5, '1');       //结果为"11111"
    string str6(str2, 2);      //结果为"3456789"
//字符串比较函数
    //"aBcd" 和 "Abcd"比较------ a > A
    cout << "A.compare(B):" << A.compare(B)<< endl; 
    // 前面减去后面的ASCII码,>0返回1,<0返回-1,相同返回0
//字符串删除函数
    str2.erase(1,6);                       // 结果:189
    //1表示坐标,6表示长度
//字符串中的字符替换
    string s1("hello,world!");
    s1.replace(6,5,"girl");           // 结果:hello,girl.
    //6表示坐标,5表示长度
//整型--字符串型转换
    int n;
    char a = to_string(n);  
​

23.9

计算机求解中缀表达式

计算机求解中缀表达式的具体步骤:

  1. 从左到右扫描中缀表达式。
  2. 如果遇到操作数(数字),则将其压入操作数栈。
  3. 如果遇到操作符(如 +, -, *, /),执行以下操作: a. 如果操作符栈为空或栈顶元素为左括号 (,则将操作符压入操作符栈。 b. 如果新操作符的优先级高于操作符栈顶的操作符,也将新操作符压入操作符栈。 c. 如果新操作符的优先级小于或等于操作符栈顶的操作符,从操作数栈中弹出两个操作数,从操作符栈中弹出一个操作符,执行相应的计算,并将结果压入操作数栈。然后,将新操作符压入操作符栈。重复此过程,直到新操作符可以被压入操作符栈。
  4. 如果遇到左括号 (,将其压入操作符栈。
  5. 如果遇到右括号 ),重复执行以下操作,直到遇到左括号 ( a. 从操作数栈中弹出两个操作数。 b. 从操作符栈中弹出一个操作符。 c. 执行相应的计算,并将结果压入操作数栈。 d. 在执行完这些操作后,弹出操作符栈顶的左括号 (。
  6. 当扫描完整个中缀表达式后,如果操作符栈仍然包含操作符,重复执行以下操作,直到操作符栈为空: a. 从操作数栈中弹出两个操作数。 b. 从操作符栈中弹出一个操作符。 c. 执行相应的计算,并将结果压入操作数栈。
  7. 操作数栈中剩余的最后一个元素就是中缀表达式的计算结果。

24.1.4 Tire

学习总结:因为用的是一个算法,所以今天写的俩题代码都挺相似的,但是刚开始没看明白,两道题都是看了两遍题解和视频然后突然恍然大悟里面一些没看明白的代码是怎么写的…就,很神奇。

感觉tire的话就相当于根据输入构建了一个二叉树进行查找,理解了以后写起来也比较简单。通过构建字节点数组son对这个二叉树进行更新,查找的时候也直接通过判断有没有这个son节点更新查找深度。 要注意里面有一个idx的变量,既表示了当前查找的节点位置,同时在插入步骤的时候把++idx赋值给新节点son,使每个节点都有一个唯一的坐标。

24.1.5 并查集

今天学的是并查集,感觉比较简单,代码简短,思维也挺巧妙的,学完会说“哇哦”的那种。

基本思路是应对集合合并查询等问题时将集合转化为树处理,设置一个p[N]数组保存每个节点的父节点;设置一个find()函数,每次返回参数节点的祖先节点(并做了路径压缩处理)。

写第二道题的时候输入的两位操作字符op写成了字符数组的形式,结果就不能进入if(op=="Q1")判断的分支,之后看了半天改成string就可以了。感觉犯了一个很基础的错误hhh

24.1.10 加权并查集

一道加权并查集:思路挺巧妙的,但是我后面调代码调了很久,最后我发现!!!是因为我初始化p[]数组的时候把i敲成了1…然后,后面debug的时候也一直一直没有看出来,我一直以为我写的是i!

因为把i认成1跟它杠了很久 最后发现的时候我简直要被我自己蠢哭qwq

24.2.16 哈希表

写了一道题,学习了哈希表的两种写法: ①拉链法:通过在每个映射的槽下面添加链表来处理直接映射导致的冲突。 ②开放寻址法:直接创建一个远大于数据限制的数组,通过查询操作插入数据,如果发生冲突就重新在数组上找一个位置放入数据。

个人感觉,拉链法应该是用空间换时间,开放寻址应该是用时间换空间的…吧

拉链法用的更多,开放寻址较少