知道做到

关于本书和作者

本书是《一分钟经理人》作者肯•布兰佳的最新力作。《知道做到》这本书从根本上剖析了“知与行”之间存在的鸿沟,并给你提供了行之有效的解决方法,教你如何把自己学到的东西落实到实际行动中,实现知行合一。

作者有三个人,他们是肯·布兰佳、保罗·梅耶、迪克·卢赫。
肯·布兰佳:是享誉全球的管理大师,同时也是作家、演说家和商业咨询顾问,被誉为当今商界最具洞察力和思想深度的人之一。他曾写过多部畅销书,其中《一分钟经理人》发行了超过25种语言的译本,缔造了总销量逾1800万册的佳绩。2005年,作为史上著名的25个畅销书作家之一,他被列入亚马逊名人堂。
保罗·梅耶:是价值数十亿美元的自我完善产业的著名先驱者和领导人,美国成功激励学院的奠基人。
迪克·卢赫:是一位非常受欢迎的动机论演说家,著名的顾问和天才培训师。

本书核心观点

从知道到做到,关键在于“重复”。
要实现从知道到做到,正确的流程应该是:

1、我知道这个事情是什么
2、我有正确的方法去执行(容易缺失的环节)
3、按这个方法执行到位

第二个步骤,是我们最容易缺失的环节,这个方法的关键,就是两个字“重复”。
不仅仅是简单的重复,而是间隔性重复,在不同的层次、不同的阶段不断地重复。

这本书讲两件事:
1、为什么知道了却做不到?三大原因和破解方法
2、从知道到做到,需要的三个步骤

一、阻碍从知道到做到的三大原因和破解方法

1、原因一,信息超载

WHY:
人们会习惯性地不断获取新事物,而并不将其付诸于实践,从而导致信息超载。这是因为人的心理会认为获取新事物要比应用已有的知识有趣得多。但事实上,重复阅读或者练习过去已经学到的知识,带来的价值非常大。比如:通过间隔性重复彻底读透少量资料对人心理所产生的影响,要超过泛读20本书所产生的影响。

HOW:解决方案是“精要主义”

从改变认知的角度,精要地学习那些真正重要的事情,而不是多而浅地接触大量信息。
做法:专注和重复。
要想掌握某个知识,必须让自己完全沉浸其中,通过间隔性重复,直到将其完全吸收。(参考得到音频《精要主义》)

2、原因二,消极过滤

WHY:
大脑学习知识的时候有个消极过滤系统,用消极心态建立防御机制,在无形中阻碍了学习新知识的热情和态度。
HOW:解决方案是“绿灯思维”

从改变态度的角度,去接纳一新事物。强迫自己在出现惯性红灯思维之前,先提出绿灯思维和黄灯思维。

做法:站在别人的视角思考,重复思考其观点的价值所在。

先积极认可一个新观点、新方法的可行之处,再提出进一步的建议,最后再抛出可能存在的危险。在发现其中的正确之处时,告诉自己“我听到的这个观点,看到的这个信息,肯定是有价值的”,同时逼自己去找出别人这个观点的价值。

3、原因三,缺少跟进

WHY:
很多人在接触了新事物后,没有制订一个跟进计划,结果是很快就恢复了旧习惯而没有任何行动和改变。

心理误区:认为采取一个行动重要的是掌握新的知识。所以人们宁愿花很多时间去学习新事物,但是却不愿意花一点点时间去跟进之后对知识的应用。

HOW:解决方案是“持续跟进”

做法:指导——支持——问责,并重复步骤。

有足够的指导,告诉自己怎么做,然后在做的过程中给出支持,不断去反馈帮助,最后问责,做得好的激励表扬,做得不好的要反馈改进。

二、从知道到做到,需要的三个步骤

第一步,改变认知,知识层面的转化(精要的学习)
第二步,改变态度,积极思维的转化(训练绿灯思维)
第三步,改变行为,跟进系统(一套具体详实的跟进计划)

每一个步骤都花时间重复,间隔性重复。

撰稿、讲述:成甲(微信公众号“个人知识管理”,搜索:pkm100)

<think>我们正在讨论C++中的`std::unique`函数,并关注如何用它来统计重复数字的个数。根据用户之前的问题,我们知道`std::unique`用于去除相邻的重复元素,但它本身并不直接返回重复元素的个数。不过,我们可以利用它来辅助统计。 思路: 1. 首先,我们需要对序列排序,因为`std::unique`只能去除相邻的重复元素。 2. 使用`std::unique`将重复的元素移到末尾,并返回一个指向新结尾的迭代器。 3. 然后,我们可以通过计算原序列长度和新序列长度的差值,得到重复元素的总个数(注意:重复元素的总个数是指所有重复出现的元素出现的次数总和,还是指重复元素的种类数?这里需要明确)。 但是,用户的问题可能是想统计每个重复元素的重复次数,或者统计总共有多少个重复出现的元素(即重复出现的次数总和)。另外,也可能是指重复元素出现的次数(即每个元素出现的次数-1)。 我们分两种情况讨论: 情况一:统计每个元素重复出现的次数(即频率) - 我们可以先排序,然后使用`std::unique`结合`std::count`或者直接遍历计数。 情况二:统计重复元素的总个数(即所有重复出现的次数,比如[1,1,2,2,3]中,重复出现的总次数是4(因为1出现2次算重复1次,2出现2次算重复1次,但通常我们统计重复出现的总次数是指超过1次的部分,即每个元素出现次数减1的和)) - 那么总重复次数 = 原长度 - 去重后的长度 例如:数组[1,1,2,2,3]: - 原长度=5,去重后[1,2,3]长度为3,则重复元素总个数=5-3=2(这里指有2个重复的元素?还是重复出现的次数?) 实际上,重复出现的次数总和应该是:每个元素重复的次数之和。对于1重复了1次(出现2次,重复1次),2重复了1次,3没有重复。所以总重复次数=1+1=2,正好等于5-3=2。 因此,我们可以用原长度减去去重后的长度来得到总的重复次数(即每个元素出现次数减1的和)。 但是,如果用户想要的是每个重复元素的重复次数(即频率统计),则需要另一种方法。 下面分别给出两种情况的代码: 情况一:统计每个元素的出现次数(使用排序和遍历) 情况二:统计重复元素的总个数(使用`std::unique`) 由于用户问题中提到了`std::unique`,我们先重点讨论情况二,然后给出情况一的代码。 情况二:统计重复元素的总个数(即重复出现的总次数) 步骤: 1. 排序 2. 调用`std::unique`得到去重后的新结尾 3. 计算重复次数:原长度 - (新结尾 - 开始位置) 代码示例(使用vector): ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 1, 2, 3, 2, 2}; // 1出现2次,2出现4次,3出现1次 // 1. 排序 std::sort(vec.begin(), vec.end()); // 2. 去重,但不删除,得到新结尾 auto last = std::unique(vec.begin(), vec.end()); // 计算去重后的元素个数 int unique_count = std::distance(vec.begin(), last); int total_duplicates = vec.size() - unique_count; std::cout << "Total duplicate elements count (total occurrences of duplicates): " << total_duplicates << std::endl; // 输出:Total duplicate elements count: 4 // 解释:1重复1次(出现2次,减去1次),2重复3次(出现4次,减去1次),所以总重复次数=1+3=4 } ``` 情况一:统计每个元素的出现次数(频率) 我们可以使用`std::map`或者排序后遍历。这里使用排序后遍历: ```cpp #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> vec = {1, 2, 1, 2, 3, 2, 2}; std::sort(vec.begin(), vec.end()); // 遍历计数 int current = vec[0]; int count = 1; for (int i = 1; i < vec.size(); i++) { if (vec[i] == current) { count++; } else { std::cout << "Element " << current << " appears " << count << " times." << std::endl; current = vec[i]; count = 1; } } // 输出最后一个元素 std::cout << "Element " << current << " appears " << count << " times." << std::endl; } ``` 但是,如果我们已经使用了`std::unique`,也可以结合`std::unique`和循环来统计。不过,更直接的方法还是遍历。 另外,如果我们只关心重复的元素(出现次数大于1),可以在遍历时只输出重复的: ```cpp // ... 排序后 int current = vec[0]; int count = 1; for (int i = 1; i < vec.size(); i++) { if (vec[i] == current) { count++; } else { if (count > 1) { std::cout << "Element " << current << " appears " << count << " times (duplicated " << (count-1) << " times)." << std::endl; } current = vec[i]; count = 1; } } if (count > 1) { std::cout << "Element " << current << " appears " << count << " times (duplicated " << (count-1) << " times)." << std::endl; } ``` 总结: - 使用`std::unique`可以快速得到重复元素的总个数(重复出现的总次数,即每个元素重复次数的和)。 - 要得到每个元素的重复次数,需要遍历计数。 注意:`std::unique`不会改变容器的容量,只是将重复的元素移到了后面,然后返回新的结尾迭代器。因此,在计算后,如果需要保留去重后的序列,可以配合`erase`使用。 现在,针对用户的问题“C++ unique function how to count number of duplicates”,我们给出了两种解释的代码。 如果用户想要的是每个重复元素的重复次数,那么情况一的代码更合适。如果用户想要的是重复元素的总个数(即重复出现的次数总和),那么情况二的代码更合适。 最后,生成相关问题。</think># C++ `std::unique` 函数统计重复数字个数详解 ## 核心原理 `std::unique` 函数本身不直接提供统计功能,但可以结合其他方法统计重复数字个数: 1. **排序数据**:`std::unique` 只能处理相邻重复元素 2. **标记重复位置**:`std::unique` 返回重复元素起始位置的迭代器 3. **计算差值**:通过迭代器差值计算重复元素个数 ## 统计重复数字的三种方法 ### 方法1:直接计算总重复个数 ```cpp #include <algorithm> #include <vector> #include <iostream> int main() { std::vector<int> data = {1, 2, 2, 3, 3, 3, 4}; // 1. 排序 std::sort(data.begin(), data.end()); // 2. 去重并获取新结尾 auto new_end = std::unique(data.begin(), data.end()); // 3. 计算总重复个数 int total_duplicates = data.size() - std::distance(data.begin(), new_end); std::cout << "总重复元素个数: " << total_duplicates << std::endl; // 输出: 总重复元素个数: 3 (2出现2次算1个重复,3出现3次算2个重复) } ``` ### 方法2:统计每个数字的重复次数 ```cpp #include <algorithm> #include <vector> #include <iostream> int main() { std::vector<int> data = {1, 2, 2, 3, 3, 3, 4}; std::sort(data.begin(), data.end()); auto it = data.begin(); while (it != data.end()) { auto next = std::upper_bound(it, data.end(), *it); int count = std::distance(it, next); if (count > 1) { std::cout << "数字 " << *it << " 重复了 " << (count - 1) << " 次" << std::endl; } it = next; } } /* 输出: 数字 2 重复了 1 次 数字 3 重复了 2 次 */ ``` ### 方法3:使用 `std::map` 统计频率 ```cpp #include <map> #include <vector> #include <iostream> int main() { std::vector<int> data = {1, 2, 2, 3, 3, 3, 4}; std::map<int, int> frequency; for (int num : data) { frequency[num]++; } for (const auto& pair : frequency) { if (pair.second > 1) { std::cout << "数字 " << pair.first << " 重复了 " << (pair.second - 1) << " 次" << std::endl; } } } /* 输出同上 */ ``` ## 方法对比 | 方法 | 时间复杂度 | 空间复杂度 | 是否修改原数据 | 适用场景 | |------|------------|------------|----------------|----------| | 直接计算 | $O(n \log n)$ | $O(1)$ | 是 | 只需总重复数 | | 二分查找统计 | $O(n \log n)$ | $O(1)$ | 是 | 需每个数字重复次数 | | std::map统计 | $O(n \log n)$ | $O(n)$ | 否 | 需保留原始数据 | ## 关键注意事项 1. **必须排序**:`std::unique` 只处理相邻元素,使用前必须排序[^1] 2. **重复定义**:重复次数 = 出现次数 - 1 3. **性能考虑**:大数据集优先使用方法1或2减少内存占用 4. **自定义类型**:需重载 `operator<` 或提供比较函数 ## 应用场景 1. 数据清洗:统计并移除重复记录 2. 数据分析:计算数据重复率 3. 算法优化:预处理减少计算量 4. 质量控制:检测重复输入错误 > 统计示例:序列 $[a, a, b, b, b, c]$ 中 > - 总重复数 = 6 - 3 = 3 > - $a$ 重复1次,$b$ 重复2次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值