ARTS 第十周打卡
Algorithm : 做一个 leetcode 的算法题
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
int iSize = strs.size();
if(iSize <= 0)
{
return "";
} if(1 == iSize)
{
return strs[0];
} int iMaxPrefix = 0;
while(true)
{
for(int i = 0; i < iSize; i++)
{
if(iMaxPrefix >= (int)strs[i].size())
{
return strs[i].substr(0, iMaxPrefix);
} char ch = strs[0][iMaxPrefix];
if(ch != strs[i][iMaxPrefix])
{
return strs[i].substr(0, iMaxPrefix);
}
}
iMaxPrefix++;
} }
};
Review : 阅读并点评一篇英文技术文章
11.1.1 Numeric Type Overview
A summary of the numeric data types follows. For additional information about properties and storage requirements of the numeric types, see Section 11.2, “Numeric
Types”, and Section 11.8, “Data Type Storage Requirements”. For integer types, M indicates the maximum display width. The maximum display
width is 255. Display width is unrelated to the range of values a type
can contain, as described in Section 11.2, “Numeric Types”.
对于整数类型,M表示最大显示宽度,最大显示宽度为255,显示的宽度与包含类型的值范围无关。 For floating-point and fixed-point types, M is the total number of digits that can be stored. As of MySQL 8.0.17, the display width attribute is deprecated for integer data types and will be removed in a future MySQL version.
从mysql8.0.17开始,对于整数数据类型,显示宽度属性被弃用; If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
如果数值列被指定ZEROFILL,Mysql会自动增加unsigned属性的值到该列; As of MySQL 8.0.17, the ZEROFILL attribute is deprecated for numeric data types
and will be removed in a future MySQL version. Consider using an alternative means of producing the effect of this attribute. For example, applications could use the LPAD() function to zero-pad numbers up to the desired width, or they could store
the formatted numbers in CHAR columns.
从mysql8.0.17开始,对于数字类型,zerofill属性将被弃用,并且将被删除在以后的版本中,考虑使用另外一种方法来替换这中属性,例如,应用程序可以使用LPAD()函数将零位数设置为所需要的宽度,或者将格式化的数字存储在char列中;
Numeric data types that permit the UNSIGNED attribute also permit SIGNED.
However, these data types are signed by default, so the SIGNED attribute has no
effect. As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE, and DECIMAL (and any synonyms) and will be removed in a future MySQL version. Consider using a simple CHECK constraint instead for such columns.
从mysql8.0.17开始,对于float/double/decimal(以及任何同义词)不推荐使用unsigned属性,并在奖励啊的版本中被删除,考虑使用简单的额CHECK来约束这些列。 SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE. SERIAL DEFAULT VALUE in the definition of an integer column is an alias for NOT NULL AUTO_INCREMENT UNIQUE.
Tips : 学习一个技术技巧
#ifndef __TIMER_AXIS_H__
#define __TIMER_AXIS_H__ #include "Common.h" #ifdef SUPPORT_TIMER #include <string>
#include <list>
#include <vector>
#include <map>
#include "TimerHandler.h"
#include "Singleton.h"
#include "StringHash.h"
using namespace stdext; // 定义数据类型
#ifdef WIN32
#include <windows.h>
#else
typedef unsigned long DWORD;
#endif #ifdef RKT_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable : 4251)
#endif namespace rkt
{ /*
* 问题:
* 1.OnCheck调用频率大于单位时间刻度时怎么处理?
* 2.多线程支持
* 3.长Timer怎么处理?
* 4.需要支持调试功能
*
* 分析:
* 1.时间轴的核心实际是一个高效的排序算法
* 2.此算法对插入删除操作要求极高
* 3.主要是插入排序,不是对一堆数字整体排序
* 4.插入排序实际最主要的要求是如何尽快找到一个值大致所在的位置
*
* 设计方案:
* 1.把时间轴分成N个刻度,每个刻度内保存此段时间内需要调用的Timer
* 2.长Timer折算成N个短Timer回调
* 3.因为在单位时间刻度内只能也只需调用几次,所以同一刻度内的Timer不需排序
* 4.完整时间轴由N个不同长度段的子时间轴组合而成,这样定时频率在1秒以下
* 需要频繁调用的定时器可以放在一个每格长度1ms长度等于1秒极度细化的时间轴中
* 以达到最高效率
* 5.避免填加删除Timer时的查找操作可以大大提高效率.
*/ //////////////////////////////////////////////////////////////////////////
/************************* TimerAxis Config *****************************/ // 推荐检查频率 : 16(ms)
// 推荐时间刻度 : 64(ms)
#define CHECK_FREQUENCY 16 //精确到16ms
#define TIME_GRID 64 // 时间轴长度
#define TIME_AXIS_LENGTH 720000 // 这个为什么分配这个值???
#define INVALID_TIMER 0xffffffff
#define INFINITY_CALL 0xffffffff // 是否允许进行定时器统计
//# define SUPPORT_TIMEAXIS_STAT #define SUPPORT_TIMEAXIS_DEBUG_INFO // 是否支持调试信息 struct SAnalyseTimer
{
public:
float m_fAvgTime;
float m_fMaxTime;
float m_fCount;
};
typedef hash_map<std::string, SAnalyseTimer> TMAP_ANALYSETYPE; struct SStatTimer
{
int m_iCount;
std::string m_szDebugInfo; SStatTimer(void)
{
m_iCount = 0;
m_szDebugInfo.clear();
}
};
typedef StrHashMap<SStatTimer> TMAP_STATTYPE; ////////////////////////////////////////////////////////////////////////// class RKT_EXPORT TimerAxis : public SingletonEx<TimerAxis>
{
public:
/**
@purpose : 设置一个定时器
@param dwTimerID : 定时器ID
@param dwInterval : 定时器调用间隔
@param pHandler : 处理接口
@param dwCallTimes : 调用次数,默认调用无穷次
@param pszDebugInfo : 调试信息
@return : 如果设置成功则返回true
*/
bool TimerAxis::SetTimer(DWORD dwTimerID, DWORD dwInterval, ITimerHandler *pHandler, DWORD dwCallTimes = INFINITY_CALL, const char *pszDebugInfo = NULL); /**
@purpose : 删除定时器
@param timerID : 定时器ID
@param handler : 处理接口
@return : 返回是否删除成功
*/
bool KillTimer(DWORD timerID, ITimerHandler *handler); /** 删除定时器对象内部的所有时钟 added by PeakGao 2011.5.3
@param handler 定时器处理者 */
void KillTimer(ITimerHandler *handler); void CheckTimer(ulong timeout = 0); TMAP_STATTYPE *GetStateInfo(void); DWORD GetTimerCount() { return m_dwTimerCount; } void OutputAnalyseInfo(); TimerAxis(); virtual ~TimerAxis(); protected:
/// 取得当前时间,你可以修改成使用其他API
inline DWORD GetTickCount() { return ::GetTickCount(); } protected:
struct Timer
{
DWORD m_dwTimerID;
DWORD m_dwInterval; // 定时器调用间隔
DWORD m_dwCallTimes; // 总共需要回调多少次
DWORD m_dwLastCallTick; // 最后一次调用的时间
DWORD m_dwGridIndex; // 所在的时间刻度
ITimerHandler *m_pHandler; #ifdef SUPPORT_TIMEAXIS_DEBUG_INFO
std::string m_pszDebugInfo;
#endif
std::list<Timer *>::iterator m_itPos; // 在时间刻度中的iterator,加快搜索
}; typedef std::list<Timer> TIMER_INFO; // 存在ITimerHandler中的定时器临时信息
typedef std::list<Timer *> TIMER_LIST; // 每一个时间刻度中存放的定时器列表
typedef std::vector<TIMER_LIST> TIMER_AXIS; // 保存所有时间刻度信息的时间轴结构 TIMER_AXIS m_astTimerAxis;
DWORD m_dwLastCheckTick; // 最后一次检查的时间
DWORD m_dwInitializeTime; // 时间轴初始时间
DWORD m_dwTimerCount; // 定时器个数 #ifdef SUPPORT_TIMEAXIS_STAT
TMAP_STATTYPE m_mapStatType; // 按定时器来统计数量
#endif
TMAP_ANALYSETYPE m_mapAnalyseType; //定时器调用 耗时分析统计表
}; } // namespace rkt #ifdef RKT_COMPILER_MSVC
#pragma warning(pop)
#endif #endif // #ifdef SUPPORT_TIMER #endif // __TIMER_AXIS_H__ #include "../Include/TimerAxis.h" using namespace rkt; TimerAxis::TimerAxis()
{
m_astTimerAxis.resize((TIME_AXIS_LENGTH + TIME_GRID - 1) / TIME_GRID);
m_dwInitializeTime = GetTickCount();
m_dwLastCheckTick = m_dwInitializeTime;
} TimerAxis::~TimerAxis()
{
for (int i = 0; i < (int)m_astTimerAxis.size(); i++)
{
for (TIMER_LIST::iterator it = m_astTimerAxis[i].begin(); it != m_astTimerAxis[i].end(); ++it)
{
Timer *pTimer = *it;
if (pTimer)
{
KillTimer(pTimer->m_dwTimerID, pTimer->m_pHandler);
}
}
}
} /**
@purpose : 设置一个定时器
@param timerID : 定时器ID
@param interval : 定时器调用间隔
@param handler : 处理接口
@param callTimes: 调用次数,默认调用无穷次
@param debugInfo: 调试信息
@return : 如果设置成功则返回true
*/
bool TimerAxis::SetTimer(DWORD dwTimerID, DWORD dwInterval, ITimerHandler *pHandler, DWORD dwCallTimes, const char *pszDebugInfo)
{
// 1.条件检查
if (NULL == pHandler || 0 == dwInterval)
{
return false;
} void **ppTimeInfo = pHandler->GetTimerInfoPtr();
assert(ppTimeInfo); TIMER_INFO *pTimerInfo = *(TIMER_INFO **)ppTimeInfo;
if (NULL == ppTimeInfo)
{
pTimerInfo = new TIMER_INFO;
*ppTimeInfo = pTimerInfo;
} // 2.检查是否已经添加这个timer
for (TIMER_INFO::iterator it = pTimerInfo->begin(); it != pTimerInfo->end(); it++)
{
if (it->m_dwTimerID == dwTimerID)
{
return false;
}
} // 3.添加一个新的定时器
Timer stTimer;
stTimer.m_dwTimerID = dwTimerID;
stTimer.m_dwInterval = dwInterval;
stTimer.m_dwCallTimes = dwCallTimes;
stTimer.m_dwLastCallTick = m_dwLastCheckTick;
stTimer.m_pHandler = pHandler; if (pszDebugInfo)
{
stTimer.m_pszDebugInfo = pszDebugInfo;
} // 计算所在的刻度
stTimer.m_dwGridIndex = ((stTimer.m_dwLastCallTick + stTimer.m_dwInterval - m_dwInitializeTime) / TIME_GRID) % m_astTimerAxis.size(); pTimerInfo->push_back(stTimer); // 4.添加到时间刻度
Timer& rstTimerRef = pTimerInfo->back(); // 这里不能使用 stTimer 临时变量
m_astTimerAxis[stTimer.m_dwGridIndex].push_back(&rstTimerRef);
rstTimerRef.m_itPos = --m_astTimerAxis[stTimer.m_dwGridIndex].end(); return true;
} /**
@purpose : 删除定时器
@param timerID : 定时器ID
@param handler : 处理接口
@return : 返回是否删除成功
*/
bool TimerAxis::KillTimer(DWORD dwTimerID, ITimerHandler *pHandler)
{
void **ppTimerInfo = pHandler->GetTimerInfoPtr();
assert(ppTimerInfo); TIMER_INFO *pTimerInfo = *(TIMER_INFO **)ppTimerInfo; // 根本就没添加
if (NULL == pTimerInfo)
{
return;
} // 检查是否已经添加了这个Timer
for (TIMER_INFO::iterator it = pTimerInfo->begin(); it != pTimerInfo->end(); it++)
{
if (it->m_dwTimerID == dwTimerID)
{
pTimerInfo->erase(it);
if (pTimerInfo->empty())
{
delete pTimerInfo;
pTimerInfo = NULL;
} return true;
}
} return false;
} /** 删除定时器对象内部的所有时钟
@param handler 定时器处理者 */
void TimerAxis::KillTimer(ITimerHandler *pHandler)
{
void **ppTimerInfo = pHandler->GetTimerInfoPtr();
assert(ppTimerInfo); TIMER_INFO *pTimerInfo = *(TIMER_INFO **)ppTimerInfo; // 根本就没添加
if (NULL == pTimerInfo)
{
return;
} pTimerInfo->clear(); delete pTimerInfo;
pTimerInfo = NULL; } void TimerAxis::CheckTimer(ulong timeout)
{
DWORD dwNowTicks = GetTickCount();
if (dwNowTicks - m_dwLastCheckTick < CHECK_FREQUENCY)
{
return;
} DWORD dwStartGrid = ((m_dwLastCheckTick - m_dwInitializeTime) / TIME_GRID) % m_astTimerAxis.size();
DWORD dwCurGrid = ((dwNowTicks - m_dwInitializeTime) / TIME_GRID) % m_astTimerAxis.size();
m_dwLastCheckTick = dwNowTicks; // 遍历所有时钟
do
{
TIMER_LIST rstTimeList = m_astTimerAxis[m_dwLastCheckTick];
for (TIMER_LIST::iterator it = rstTimeList.begin(); it != rstTimeList.end();)
{
Timer* pTimer = *it;
if (NULL == pTimer)
{
it = rstTimeList.erase(it); // 删除会指向下一个元素
continue;
} if (dwNowTicks - pTimer->m_dwLastCallTick >= pTimer->m_dwInterval)
{
// 触发定时器
pTimer->m_pHandler->OnTimer(pTimer->m_dwTimerID); pTimer->m_dwLastCallTick = dwNowTicks;
pTimer->m_dwCallTimes -= 1; if (0 == pTimer->m_dwCallTimes)
{
KillTimer(pTimer->m_dwTimerID, pTimer->m_pHandler);
}
else
{
pTimer->m_dwGridIndex = ((pTimer->m_dwLastCallTick + pTimer->m_dwInterval - m_dwInitializeTime) / TIME_GRID) % m_astTimerAxis.size();
it = rstTimeList.erase(it);
m_astTimerAxis[pTimer->m_dwGridIndex].push_back(pTimer);
pTimer->m_itPos = --m_astTimerAxis[pTimer->m_dwGridIndex].end();
continue;
}
} it++;
} // 递进大下一个刻度
if (dwStartGrid == dwCurGrid)
{
break;
} dwStartGrid = (dwStartGrid + 1) % m_astTimerAxis.size(); } while (dwStartGrid != dwCurGrid);
} TMAP_STATTYPE *TimerAxis::GetStateInfo(void)
{
} void TimerAxis::OutputAnalyseInfo()
{
}
Share : 分享一篇有观点和思考的技术文章
C++ new delete 常踩的坑
ARTS 第十周打卡的更多相关文章
- ARTS第十周
之前忘了发布 1.Algorithm:每周至少做一个 leetcode 的算法题2.Review:阅读并点评至少一篇英文技术文章3.Tip:学习至少一个技术技巧4.Share:分享一篇有观点和思考的 ...
- ARTS 第八周打卡
Algorithm : 做一个 leetcode 的算法题 13. 罗马数字转整数 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I ...
- ARTS第七周打卡
Algorithm : 做一个 leetcode 的算法题 ////////////////////////////////////////////////////////////////////// ...
- ARTS第六周打卡
Algorithm : 做一个 leetcode 的算法题 1.合并两个排序链表 2.树的子结构 3.二叉树的镜像 4.包含Min函数的栈 5.栈的压入.弹出 6.二叉搜索树的后序遍历 7.从上往下打 ...
- 2017-2018-1 20155232 《信息安全系统设计基础》第十周课堂测试(ch06)补交
# 2017-2018-1 20155232 <信息安全系统设计基础>第十周课堂测试(ch06)补交 上课时完成测试后在提交的时候,没有提交成功,进行补交. 1.下面代码中,对数组x填充后 ...
- 第十周 psp
团队项目PSP 一:表格 C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论用户界面 8:45 10:55 40 35 90 分析与 ...
- Java 第十周学习总结
20145113<Java程序设计>第十周学习总结 基础知识 1.网络通讯的方式主要有两种 TCP(传输控制协议)方式:需要建立专用的虚拟连接以及确认传输是否正确 UDP(用户数据报协议) ...
- 第十周PSP
第十周PSP 工作周期:11.17-11.24 本周PSP: C类型 C内容 S开始时间 ST结束时间 I中断时间 T净时间(分) 文档 写随笔(PSP) 16:20min 16:50min 0 ...
- 20145213《Java程序设计》第十周学习总结
20145213<Java程序设计>第十周学习总结 教材学习总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接 ...
随机推荐
- 用Python实现自己下载音乐的统计
今天看Python实例,学习了如何对文件进行操作,突然想把自己网易云音乐下载到本地的歌曲名单写到一个txt中,看看具体情况.当然,我现在肯定无法做到直接去网易云音乐上爬取,就做个最简单的吧,嘻嘻^-^ ...
- mysql的存储引擎与锁
一.背景知识 1.锁是计算机协调多个进程或线程并发访问某一资源的机制. A.锁分类. | 共享锁(读锁):在锁定期间,多个用户可以读取同一个资源,读取过程中数据不会发生变化. | 排他锁(写锁):在锁 ...
- 简述*args and **kwargs
为了能让一个函数接受任意数量的位置参数:* 为了接受任意数量的关键字参数:** *参数只能出现在函数定义中最后一个位置参数后面,而**参数只能出现在最后一个参数 解决的问题:构造一个可接受任意数量参数 ...
- P3180 [HAOI2016]地图
P3180 [HAOI2016]地图 显然,这是一个仙人掌图 inline void tarjan(LL u,LL fa){ low[u]=dfn[u]=++tot, pre[tot]=u; for( ...
- Java学习日记基础篇(九) —— 集合框架,泛型,异常
集合框架 有事我们会需要一个能够动态的调整大小的数组,比如说要添加新员工但是数组已经满了,并且数组的大小是在定义的时候定死的,所以我们就需要一个能够动态调整大小的数组或者用链表解决,而java中提供了 ...
- Java 代码编写单例模式总结
手写一个单例模式是 Java 面试中常见的问题,很多时候我们更偏向于简单的写一个饿汉或饱汉模式,深入研究的甚少,这里列举三种实现方式,并对各自的优缺进行分析. 1. 饿汉式 public class ...
- OpenJudge计算概论-矩阵交换行
/*======================================================================== 矩阵交换行 总时间限制: 1000ms 内存限制: ...
- BitmapShader填充图形
package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.*; imp ...
- ISO/IEC 9899:2011 条款6.4.1——关键字
6.4.1 关键字 语法 1.以下为关键字: auto break case char const continue default do double ...
- 123457123456#0#-----com.twoapp.ErTongHuaHua01--前拼后广--儿童绘画填色游戏jiemei
com.twoapp.ErTongHuaHua01----儿童绘画填色游戏jiemei