Fork me on GitHub

C++:结构体、vector、队列、链表、哈希表、映射map、简述回顾O(logn)复杂度、哈希表和桶排序里的“桶”、set

 

 

好奇怪不知道为啥唯独这个标题有目录

 

菜鸟教程:结构体 ~ 数据结构

 

C++ 结构体(struct)

 

基础知识:

1、数据项:

指的是数组或结构体中存储的具体数据,在数组里是相同类型的单个数据,在结构体里则是不同类型的单个数据,它们是构成数组和结构体这些数据集合的基本元素。

2、结构体(structure),用于定义结构体,它告诉编译器后面要定义的是一个自定义类型。

3、

  • 访问权限:与 class 类似,你可以在 struct 中使用 public、private 和 protected 来定义成员的访问权限。在 struct 中,默认所有成员都是 public,而 class 中默认是 private。

4、

关于: ->和 .,这节讲了

之前博客里搜“到这想到了几个问题”提前问了豆包

5、关于typedef上面的两段内容:

——  指向结构体的指针
——  结构体作为函数参数

简化两个代码,进行理解

#include <iostream>
#include <string>
using namespace std;
struct Books{
    string title;
    int book_id;
//    Books(string t, int id)
//        : title(t), book_id(id) {}
};
void printBookInfo(const Books& book) {
    cout << "书籍标题: " << book.title << endl;
    cout << "书籍 ID: " << book.book_id << endl;
}
int main(){
    Books Book1;//("C++ 教程",12345);
    Book1.title="C++ 教程";
    printBookInfo(Book1);
}

/*以上指向结构体的指针
以下结构体作为函数参数*/

//#include <iostream>
//#include <cstring>
//using namespace std;
//void printBook( struct Books book );
//struct Books{
//   char  title[50];
//   int   book_id;
//};
//int main(){
//   Books Book1;
//   strcpy( Book1.title, "C++ 教程");
//   Book1.book_id = 12345;
//   printBook( Book1 );
//}
//void printBook( struct Books book ){
//   cout << "书标题 : " << book.title <<endl;
//   cout << "书 ID : " << book.book_id <<endl;
//}

① 

  • 如果函数参数使用了 const 修饰,在函数内尝试更改传入对象会导致编译报错,因为 const 表明该对象在函数内不可修改。
  • 不写 const 时,函数内部可以对传入的对象进行修改,因为没有了只读限制。

  • Books& book这种写法是引用传递,引用作为对象的别名,在函数调用时直接使用对象名传入即可,引用传递避免了对象的复制,提高效率。

具体解释:

在 C++ 中,引用就像是给已存在的对象起了一个额外的名字。当你定义 Books& book 时,book 就是某个 Books 类型对象的别名。这意味着 book 和它所引用的对象其实是同一个东西,它们共享同一块内存空间。
打个比方,一个人叫 “张三”,他还有个小名 “三儿”,不管喊 “张三” 还是 “三儿”,指的都是同一个人。同样的道理,book 就类似于这个小名,它和被引用的对象本质上是一体的。

对引用传递里的形参操作,就是对传递进来的实参操作

上述代码的指向结构体的指针部分,即上部分的那段代码,如果printBookInfo不是const,则可以book.title = "新的书名";改变传入对象Book1.title的值

好处:

引用传递避免对象复制,提高效率
void printBook( struct Books book )这种就叫值传递(struct可以省略),复制了对象。且在这个函数里对book的修改不会影响main函数中的Book1
 
  • Books& book表示bookBooks类型对象的引用,对book的操作实际上就是对传入的Books对象本身进行操作。

  • Books(string t, int id) : title(t), book_id(id) {}Books结构体的构造函数,用于创建 Books 对象时初始化成员变量,使用成员初始化列表的方式对titlebook_id成员变量进行初始化。
    (string t, int id) 是参数列表,冒号后 title(t), book_id(id) 是成员初始化列表,将传入参数 tid 分别赋给 titlebook_id

构造函数:

对于这里的构造函数,可以不写

但如果写了构造函数,即为有参构造函数,那创建Book1时候用无参形式Books Book1;会出错,要这样Books Book1("C++ 教程",12345);Books Book1 后括号内可以直接写初始化值来调用构造函数初始化对象。因为有参构造函数会让默认构造函数(即无参构造函数)不再自动生成,若无额外提供无参构造函数,使用 Books Book1; 会编译报错,也就无法先默认构造对象再进行成员赋值初始化

 

有参构造函数存在时,也是可以用 Book1.title = "aa"; 这种方式赋值的,前提title是string类型,如果是字符数组要用strcpy,但这和初始化概念不同。
  • 初始化:是在对象创建时就赋予其初始值,比如使用有参构造函数 Books Book1("aa", ...);,在对象 Book1 创建的同时就完成了成员的赋值操作。
  • 赋值:是对象已经创建完成后,再对其成员进行值的修改。Book1.title = "aa"; 就属于赋值操作,前提是 Book1 对象已经被成功创建。

 

结构体里有构造函数时候,下面主函数main里创建的时候,必须有初始化。而没构造函数的时候,初步初始化都行。更严谨的说法:

在 C++ 里,结构体有构造函数时,若构造函数无默认参数则创建对象时必须按构造函数要求初始化,若有默认参数可不显式初始化;结构体无构造函数时,可进行默认初始化(如默认构造,成员有默认值等)、值初始化(如用 {} 语法)等初步初始化方式,但不是仅局限于初步初始化,也可按需后续赋值等操作。

 

对于结构体:

struct 在 C 和 C++ 里都叫结构体,在创建该类型时,C 里称该类型的结构体变量,C++ 里一般叫对象或者实例。

  • 与之前代码的区别在于此代码使用字符数组存储标题,并且printBook函数采用值传递,会复制一份对象副本进行操作,而之前代码使用std::string和引用传递,引用传递直接操作原对象,避免了复制开销。

之前也遇到过忘记了,更加理解构造函数

 

—————————————————————— C++ vector 容器 ———————————————————————

 

C++ vector 容器(之前刷题的时候被不得已总用这玩意,没深究过

在 C++ 里,std::vector是一个动态数组容器,所谓 “整型向量” 指的是std::vector<int>这种存储元素类型为整数的vector容器,它能动态调整大小,可像数组一样存放多个整数元素,既可以创建为空容器后续添加元素,也能在创建时指定初始大小和初始值。
 
 
for (int element : myVector) {
    std::cout << element << " ";
}

element要素是随便起的变量名。

 

myVector.erase(myVector.begin() + 2); // 删除第三个元素

 

———————————————————— C++ 数据结构 —————————————————————————

 

C++ 数据结构

关于

struct Person {
    string name;
    int age;
};
Person p = {"Alice", 25};
cout << p.name << endl; // 输出 Alice

这里出现了跟之前不同的初始化

首先明白,这属于聚合初始化,Person是聚合类型,Person p = {"Alice", 25};通过花括号列表按成员声明顺序依次给nameage赋值,是一种简洁的初始化结构体对象方式,不同于显式构造函数初始化。

聚合类型是结构体的一种,如果用户没自定义构造函数,无私有或受保护非静态数据成员、无基类、无虚函数这些条件的结构体就是聚合类型,

而若结构体里有构造函数Person(string n, int a) : name(n), age(a) {},则不是聚合类型,就要用Person p("Alice", 25);

若有默认构造函数Person() = default;,可Person p;后再逐个成员赋值;

若有带默认参数构造函数Person(string n = "Bob", int a = 20) : name(n), age(a) {},可按需传参如Person p1; 意思是你没有提供任何实参,那么编译器会使用这些默认值来初始化对象 p1。所以 p1 的 name 成员会被初始化为 "Bob"age 成员会被初始化为 20。这就相当于调用了 Person p1("Bob", 20);

或者:Person p2("Eve", 30); ,在这种情况下,构造函数不会使用默认值,而是使用你提供的实参来初始化对象 p2。所以 p2 的 name 成员会被初始化为 "Eve"age 成员会被初始化为 30

 

类class和struct结构体一样,只不过更强大,支持继承、封装、多态等特性

 

妈逼的这教程这牛逼,要不是我之前刷过算法题懂一些,真看不懂,讲的太跳跃了,也没啥思维连贯性,都要自己脑海里整理,不过对我来说是最好的了,我只需要指路人

 

关于单向链表

struct Node {
    int data;
    Node* next;
};
Node* head = nullptr;
Node* newNode = new Node{10, nullptr};
head = newNode; // 插入新节点

这段代码定义了一个名为 Node 的结构体,包含一个整数成员 data 和一个指向下一个 Node 类型对象的指针 next,接着声明了一个指向 Node 的指针 head 并初始化为 nullptr 表示链表为空,然后使用 new 运算符动态分配一个 Node 对象,将其 data 成员初始化为 10,next 指针初始化为 nullptr,并让指针 newNode 指向该对象,最后将 head 指向 newNode,也就是把新创建的节点作为链表的头节点,完成了新节点的插入操作,此时链表中有一个节点,其数据为 10。

 

真正的算法题,都是最朴素的招式,我刷邝斌专题都没用过指针,双端队列更是没用过

然后打codeforce的GoodBye2024就他妈给我干的心灰意冷,全是数学和DP,仿佛邝斌都是模板题

╮(╯▽╰)╭~~~~(>_<)~~~~╮(╯▽╰)╭

双端队列

deque<int> dq;
dq.push_back(1);
dq.push_front(2);
cout << dq.front(); // 输出 2
dq.pop_front();

在双端队列 deque 里,front 指的是队列的头部,也就是最前面的位置。dq.push_front(2) 是在头部插入元素 2,dq.front() 用于获取头部元素(这里就是 2),dq.pop_front() 是删除头部元素;与之对应的另一端是尾部,dq.push_back(1) 是在尾部插入元素 1 ,可使用 dq.back() 获取尾部元素,用 dq.pop_back() 删除尾部元素。

 

哈希表

英文名叫:Hash Table

C++里用的时候是:unordered_map

映射

这玩意就是我之前刷题的时候用的map

放在一起说,以下都是现问的豆包,现学的热乎的

刷题跟学这些玩意完全是两种感觉,刷题的时候不想深入研究vector和map这些,甚至咋都不能熟练用,而现在学这些的时候,不想去回忆算法

哈希表和映射知识点:

std::unordered_map

  • 它基于哈希表实现,前面已经详细介绍过,能快速根据键查找值,平均时间复杂度为 O(1) 。不过它不保证元素的顺序,内部元素是无序存储的。就像你刚刚遇到的场景,把字符组合和数字对应起来,使用 std::unordered_map 就很合适。

std::map

  • std::map 基于红黑树(一种自平衡的二叉搜索树)实现。它会根据键的大小对元素进行排序,插入、删除和查找操作的时间复杂度都是 O(logn)  

举个例子:

#include <iostream>
#include <map>
#include <string>
#include<unordered_map>
using namespace std;
int main() {
    std::unordered_map <std::string, int> myMap;
    myMap["gb"] = 1;
    myMap["fd"] = 2;
    myMap["ab"] = 3;

    for (const auto& pairr : myMap)
        std::cout << "Key: " << pairr.first << ", Value: " << pairr.second << std::endl;

    cout<<"\n\n"<<endl;
    std::map<std::string, int> myMap1;
    myMap1["bb"] = 1;
    myMap1["cd"] = 2;
    myMap1["ab"] = 3;

    for (const auto& pair : myMap1)
        std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}

输出

这段代码上部分是哈希表,下部分是map,即映射

map的输出是按照键的顺序(当键是像 intdoublechar 这类基本数据类型时,std::map 会按照数值大小或者字符的 ASCII 码值进行排序。对于自定义的类可以重载比较符,来定义用类里的哪个成员变量为参照做排序比较,这里记得刷带权最短路还是啥用过,那个重载weight的)

 

这里pairr是自己随便定义的变量名,为了区别于std::pair

 

& 表示引用。这里使用引用的目的是避免在遍历过程中对 std::pair 对象进行复制,直接引用容器中的元素,提高效率。

 

pairr这是自定义的变量名,代表在循环的每次迭代中从容器中取出的元素。在 std::map 的场景下,pairr 就是一个键值对,你可以通过 pairr.first 访问键,通过 pairr.second 访问值。
 

myMap

这是要遍历的容器对象,即前面定义的 std::map

 

std::pair 确实是 C++ 标准库中的一个模板类,用于将两个不同类型的值组合成一个对象,常用于表示键值对。
在 for (const auto& pair : myMap) 里,pair 的确是你自定义的变量名,虽然它和 std::pair 重名,但这里不会产生冲突。这是因为在这个上下文中,pair 只是一个代表从 myMap 里取出的每个元素的临时变量。编译器会根据 myMap 元素的实际类型,把 auto 推导成 std::pair<const std::string, int> 类型。

 

性能特点

  • 插入和删除操作
    • std::map:插入和删除操作的时间复杂度为O(logn) ,因为需要维护红黑树的平衡。
    • std::unordered_map:平均时间复杂度为O(1) ,但在哈希冲突较多的情况下,性能可能会下降。
  • 查找操作
    • std::map:查找操作的时间复杂度为O(logn) ,通过二分查找在红黑树中定位元素。
    • std::unordered_map:平均时间复杂度为O(1) ,通过哈希函数直接计算元素的存储位置。

内存占用

  • std::map:由于红黑树需要额外的指针来维护树的结构,因此内存占用相对较高。
  • std::unordered_map:哈希表需要一个哈希表数组,并且在哈希冲突时可能需要使用链表或其他方式来解决冲突,内存占用也会有一定开销,但在某些情况下可能比 std::map 更节省内存。

std::map 与哈希表(std::unordered_map)的使用场景

  • std::map:适用于需要元素按照键有序存储的场景,例如需要对元素进行范围查找、顺序遍历等操作。
  • std::unordered_map:适用于对查找、插入和删除操作的时间复杂度要求较高,且不关心元素顺序的场景

 

注意用哈希表unordered_map需要用std且引入头文件<unoredered_map>

之前博客提过,搜“不能直接用”

 

关于 O(1) 和 O(logn) ,参考博客

O(1):

表示常数时间复杂度。这意味着无论输入规模 n 有多大,算法的执行时间都是一个固定的常数,不随输入规模的增加而增长。例如,访问数组中指定下标的元素,或者在哈希表中查找一个元素(平均情况下),这些操作的时间复杂度都是 O(1)

O(logn):

O(logn)表示对数时间复杂度。这里的对数通常是以 2 为底,但在大 O 表示法中,对数的底数不影响复杂度的量级。当输入规模 n 增加时,算法的执行时间会随着 n 的对数增长。常见的具有 O(logn) 时间复杂度的算法有二分查找,它每次将搜索范围缩小一半。

哪个更大

当输入规模 n 足够大时, O(logn)的增长速度比O(1)  快。
也就是说,O(logn) 的复杂度大于 O(1) 

Windows 计算器标准模式下的 “log” 是以 10 为底,科学模式和程序员模式里 “log” 同样默认以 10 为底,不过科学模式中有 “ln” 按钮,它是以自然常数 e 为底的对数运算

 
 

另外注意

哈希表的第一个代码里,输出的是231 f a g 开头的,这并不是进行了类似map的某种排序,而是哈希表的底层实现机制:

std::unordered_map 基于哈希表实现。哈希表的工作方式是利用哈希函数把键(key)映射到一个固定大小数组的特定位置(也称为桶,bucket)。当你插入一个键值对时,哈希函数会根据键计算出一个哈希值,然后根据这个哈希值找到对应的桶来存储该键值对。

myMap["gb"] = 1;
myMap["fd"] = 2;
myMap["ab"] = 3;

哈希函数会分别对 "gb""fd" 和 "ab" 计算哈希值,然后将这些键值对存储到相应的桶中。由于不同的键可能会计算出相同的哈希值(哈希冲突),因此每个桶可能会存储多个键值对,通常会使用链表或者更复杂的数据结构来处理这些冲突。

如果你希望按插入顺序遍历元素,可以使用 C++11 引入的 std::unordered_map 和 std::list 结合的方式来模拟有序插入的无序映射,或者考虑使用 Boost 库中的 boost::unordered_flat_map 等有序插入的无序容器实现。

 
 

Q:

为啥不直接按照输入的存储顺序存入?搞这么麻烦

A:

设计目的

std::unordered_map 的核心设计目标是提供快速的键值查找操作。它通过哈希表这种数据结构,使得在平均情况下,查找、插入和删除操作的时间复杂度能达到 O(1)。为了实现这个高效的查找性能,它更关注如何让键能够快速映射到对应的存储位置,而不是维护元素的插入顺序。

例如,在一个需要频繁查找特定键对应值的场景中,如数据库索引、缓存系统等,std::unordered_map 能快速定位到所需元素,而元素存储顺序对这些操作并没有影响。

底层实现

std::unordered_map 基于哈希表实现,其工作流程如下:

  1. 哈希计算:当插入一个键值对时,首先使用哈希函数对键进行计算,得到一个哈希值。这个哈希值通常是一个整数,它会被映射到哈希表的一个特定位置(桶)。

  2. 存储到桶中:根据计算出的哈希值,将键值对存储到对应的桶里。如果多个键计算出的哈希值相同(即发生哈希冲突),就需要采用特定的冲突解决策略,如链表法(将冲突的元素以链表形式存储在同一个桶中)或开放寻址法(寻找其他可用的桶)。


由于哈希函数的计算和桶的分配是基于键的哈希值,而不是插入顺序,所以元素最终的存储位置和插入顺序没有直接关系。

性能和空间权衡

如果要同时维护元素的插入顺序和提供快速查找功能,会带来额外的性能和空间开销。例如,可以通过额外的数据结构(如链表)来记录插入顺序,但这会增加插入、删除操作的复杂度,也会占用更多的内存空间。而 std::unordered_map 为了保证查找性能和节省空间,选择不维护插入顺序。

如果确实需要按照插入顺序存储和访问元素,可以考虑使用 std::map(按键排序存储)或 std::list 与 std::unordered_map 结合的方式,或者使用 std::unordered_map 之外专门设计的有序容器,如 Boost 库中的 boost::unordered_flat_map
 
 

Q:

所以每次都需要做计算操作来计算出位置然后存进去,要比开一块内存直接顺序存储输入的元素更快?感觉不对啊,直接开一块内存,顺序存然后需要啥直接拿不是更快吗?

A:

你提出的 “直接开一块内存,顺序存然后按需直接拿” 的方式,类似于使用数组或 std::vector 这样的顺序容器,这种方式和 std::unordered_map 在不同场景下各有优劣,下面具体分析为什么 std::unordered_map 在某些情况下更快。

顺序存储(数组或 std::vector)的局限性

查找操作

假设你用顺序容器来存储键值对,例如一个存储 std::pair<std::string, int> 的 std::vector。当你要查找某个特定键对应的值时,需要遍历整个容器,逐个比较键是否匹配。在最坏情况下,查找操作的时间复杂度是 O(n),其中  是容器中元素的数量。随着元素数量的增加,查找时间会线性增长。

插入和删除操作

如果要在顺序容器中插入或删除元素,可能需要移动后续的元素来保持连续性,这也会带来 O(n)  的时间复杂度,特别是在容器中间插入或删除元素时

 

std::unordered_map 的优势

查找操作

std::unordered_map 基于哈希表,通过哈希函数将键映射到一个特定的位置(桶)。在理想情况下,哈希函数能将键均匀地分布到各个桶中,这样查找操作只需要计算一次哈希值,然后在对应的桶中查找元素。平均时间复杂度为 O(1),这意味着无论容器中有多少元素,查找操作的时间基本保持不变。

插入和删除操作

插入和删除操作同样受益于哈希表的特性。在平均情况下,插入和删除操作的时间复杂度也是 O(1),因为只需要计算哈希值,找到对应的桶,然后在桶中进行插入或删除操作。

适用场景

  • 顺序容器:当你主要进行顺序访问,或者元素数量较少且查找操作不频繁时,顺序容器是一个不错的选择,因为它们的实现简单,内存使用效率高。
  • std::unordered_map:当你需要频繁进行查找、插入和删除操作,并且元素数量较大时,std::unordered_map 能提供更好的性能。
综上所述,虽然 std::unordered_map 在插入时需要计算哈希值,但它在查找、插入和删除操作上的平均性能优势明显,特别是在处理大规模数据和频繁操作的场景下。

 

Q:

你提到的桶,是桶排序吗?

A :
这里的 “桶” 和桶排序中的 “桶” 概念有相似之处,但在 std::unordered_map 和桶排序里,它们的具体用途和操作方式存在差异,下面为你详细解释:

std::unordered_map 中的桶

概念

在 std::unordered_map 所基于的哈希表实现里,“桶”(bucket)是一个基本的存储单元。哈希表本质上是一个数组,每个数组元素就是一个桶。当你向 std::unordered_map 插入一个键值对时,会先对键应用哈希函数,得到一个哈希值,再把这个哈希值映射到哈希表数组的某个索引位置,这个位置对应的数组元素就是要存储该键值对的桶。

用途与操作

  • 存储元素:每个桶可以存储一个或多个键值对。如果多个键通过哈希函数计算得到了相同的哈希值(即发生哈希冲突),这些键值对就会被存到同一个桶中。通常会使用链表或者更复杂的数据结构(如红黑树,当链表元素较多时为了提高查找效率会转换)来存储桶内的多个键值对。
  • 查找元素:查找时,先计算键的哈希值确定对应的桶,然后在桶内查找该键值对。
 

桶排序中的桶

概念

桶排序是一种排序算法,其中的 “桶” 也是一种容器。在桶排序里,会根据数据的取值范围将其划分成多个区间,每个区间对应一个桶。然后把待排序的数据元素分配到相应的桶中,每个桶内的数据再单独进行排序(通常使用其他排序算法,如插入排序),最后按桶的顺序依次取出元素,就得到了有序序列。

用途与操作

  • 数据分配:将待排序的数据根据其值分配到不同的桶中,使得每个桶内的数据大致有序。

  • 桶内排序与合并:对每个桶内的数据进行排序,之后按顺序将各个桶内排好序的数据合并起来

总结

虽然两者都使用了 “桶” 这个概念,但在 std::unordered_map 中,桶是用于哈希表存储和快速查找键值对的基本单元;而在桶排序中,桶是用于数据划分和辅助排序的容器,目的是将数据分类并最终实现排序。
 
 
在 C++ 的 std::unordered_map 和 std::map 这类关联容器中,键值对是以 std::pair 对象的形式存储的,其中第一个元素是键(key),第二个元素是值(value)。

 

键值对的键可以不是数字,std::unordered_map 会用哈希函数把非数字键转化为整数哈希值,再通过取模等操作将哈希值映射到哈希表的桶位置以计算存储位置。

 

之前考研的时候哈希表学过,大概有印象是怎么处理计算位置的,不纠结了

 

 

set集合

set仅存储单一元素,元素本身就是键且唯一,map存储键值对,通过键来关联值,查找时set关注元素存在性,map更侧重通过键获取对应的值。

 

 

 

###:

未曾清贫难成人,不经磨砺永天真

一群滥用的傻逼玩意,难怪总崩溃妈逼的

呵呵曾经的我

组长,你们都成家了我留下来吧,呵呵,刚到新疆,一个人硬刚公司仨区域老大,房子耗子房东耍无赖,12345民警社区,警察110住建部,都tm一群傻逼废物,呵呵,曾经无比稚嫩,如今才工作一年,有了别人10年的经历阅历,有了引以为傲的阅历,可是又怎样呢?

 

阿波罗github灌水,香烟瓜子火腿肠,矿泉水,来来来腿收一收

 

钻研精神
开悟人性

各种

我却为何一直起不来

那几年因为bb得B照顾AI_Zheng,
我那几年走错了

真的永远无法翻身吗,看着这群傻逼玩意小丑一样,开悟了又如何,钻研精神又如何,思考的深又如何,呵呵
一无是处穷途末路,傻逼废物垃圾废人

也无法变现


 

没钱我不可能向父母要
虽然要就会给,但我要自己想办法

家不回?不,爸爸期望我
必须回去
车自己想办法
其他自己想办法
乌鲁木齐到哈尔滨硬座78h443元,

 

那个百色性侵的女生,社会就是这样的,没办法,这个男老师最后一点儿惩罚都不会有。这个社会就是这样,你tm就应该就拉他一起去自杀,应该是先弄死他。哪有鸡巴毛善恶对错,操,站在那些统治者的立场就是不要给我惹事情,平息再平息,死个人算什么呀,底层人垃圾的命又不值钱,最好的办法就是底层人的命不值钱,把这件事压下去,这些垃圾人的命不值钱,翻不起什么花浪,压下去又能怎么样呢?呵呵,我看得太透彻了这些

 

我就是这个底层人,可我也想活着,挣扎着从这个烂泥堆里爬出去

 

乌鲁木齐硬座回哈尔滨过年,回程的时候,发现好几小时的硬座很满足,只要没百根抽烟臭烟味呛死人,哪怕继续羽绒服车捂头满头大汗,烤炉,强光睡觉伸不开腿,埋汰的车上环境,人也很遭烂,我都可以忍受,甚至觉得很满足,车厢不让吸烟?呵呵哪有什么法制和法律

列车员反应“他说没办法,都不关门”,麻痹的给我耍老油条,我“大哥你说我打12306给你举报一下子你是不是也挺难受?我作为乘客没权利说容易起冲突,你作为列车员吆喝两句起码也算是做了,大家也能注意点,也不是啥大事,”呵呵训的我肺疼,睡觉被呛醒,这群打工的农民工都闻不到了。车上就像一个上世纪美国那个押运黑奴一样,很满足的是,不用铁丝给你穿起来

 

 

曾经的我呵呵,做任何事都有闭环,负责,相当靠谱,最后换来了什么,职场、寝室满地吐痰凌晨6点睡觉的汽车厂维族人室友外放大声睡觉,也磨练了我的意志力、屋子里有耗子,被房东坑,硬刚那些部门呵呵有屁用,我组织带团骑行圈呵呵咋样了

痛恨曾经那么善良真诚的我自己,现在看到任何人,都最先想到可以利用的工具,看到犹如曾经的我一样的人最先想到怎么拿捏他,呵呵回不去了




底层垃圾堆里这样太吃亏太吃亏了




过年乌鲁木齐回哈尔滨443硬座,挨饿忍着一切,也要花小一千,给家人买东西,让他们知道我过的很好,我相信自己有翻身之日,公务员体制内?呵呵无非是底层的垃圾变成了国家的走狗而已无知的废物?没有背景干个屁,哪有公平正义,只有绝对的实力才可以摆平一切

 清晰的知道社会的运转逻辑,规则。呵呵

好多去年一起玩,滑雪的、骑行的、各种北京土著女生,私聊单独找我玩,赚的多的女生,呵呵不再去回复他们,一年,经历了这么多,而他们还是之前那样玩呢,呵呵,今天还有个女生主动找我要单独和我出去玩,呵呵懒得理会这群人,清晰的知道自己想要什么。路上图书馆各种地方不会因为有女生因为我长得帅总看我而内心心境有任何的波动,清晰的沉淀自己知道自己想要什么、

我想着怎么才可以有投资头脑经商头脑,逢年过节赚这些傻逼韭菜的钱,曾经会因为好几个北京土著女生或许因为我真诚,性格好,长得帅,摄影好,喜欢运动骑行,总约我玩,

会因为很久不联系总有北京土著主动打视频找我玩,

会因为有这些北京女生做朋友哦主动约我而有强烈的虚荣心,炫耀,如今不会了,不会再因为有XX怎样的朋友,而有任何觉得自豪的幼稚想法,独自面对一个人抗,成长磨砺,在外闯荡遇到事处理事说话的气场气质磁场节奏呵呵那些人一辈子不会有跟12345说“我Xx如果你们”




也学会了虚与委蛇,不会再正义的刺头,而是遇到相当大的纠纷争论矛盾最先微笑,心里想着万般手段有机会下死手绝不手软

 
View Code

 

posted @ 2025-02-12 19:09  GerJCS  阅读(43)  评论(0)    收藏  举报