有个小问题问一下大家,关于std::string快速枚举的

比如我这里需要匹配一系列的字符串:mp4、avi、mpeg3、mpeg4、3gp、mov、flv、f4v、ts、m4a

我要在得到文件名后缀之后,比如1.avi我得到了avi,那么我怎样知道他在上面的集合中?如果不在我就让他去匹配图片类型的集合。

怎样能更快速一些?用map比普通的字符串匹配要快,但是已经是最快的了么?


分数略少,求帮助啊!


用map也只是想法,晚上再来写测试代码。。
...全文
237 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
是啊,我才发现都是需要匹配的,我这边设置的字符串是null,这样就能知道数组的末尾。 不过,和你的毕竟,我这边确实是多了一次strcmp的调用;它内部也是匹配单个字符的; 你的更改数据的时候,需要改两个表。不过性能略优。

#include "stdafx.h"
#include "iostream"
#include "string"


static char const* file_gather[] = 
{
	".mp3", 
	".mp4",
	".avi",
	".mov",
	".mpeg",
	"null"
};


int _tmain(int argc, _TCHAR* argv[])
{
	std::string test_file_path = "c:\\a.avi";

	int which = test_file_path.find_last_of(".");
	std::string extend_name = test_file_path.substr(which, test_file_path.length());

	std::cout << "extend_name value is : " << extend_name << std::endl;

	int index = 0;
	bool is_can_play_type = false;
	while (true)
	{
		if (!strcmp(file_gather[index], "null"))
		{
			break;
		}
		else
		{
			if (!strcmp(extend_name.c_str(), file_gather[index]))
			{
				is_can_play_type = !is_can_play_type;
				break;
			}
		}
		index++;
	}

	std::cout << "is_can_play_type value is : " << is_can_play_type << std::endl;

	return 0;
}


引用 17 楼 zengraoli 的回复:
后来在看了一下代码觉得前面部分,貌似是多余的;而且枚举和int的转换,vs编译不能通过,试过08、10、12、13版本的 昨晚没细看,以为是只用enum类型,原来还是匹配字符串的方式。
1. 不管你用什么方法都避免不了字符串的遍历:使用hash也是从char*->int, map,set等用的就是字符串匹配。 鉴于你的媒体类型不会太多,直接用逐个匹配就好了。 2. 通不过编译的问题,稍加修改就好。

#include <cstring>
enum media_type
{
	mp3,
	mp4,
	media_type_cnt
};
#define unkown_type (enum media_type)-1;

enum media_type convert(char const* type);
void play(char const* fn, enum media_type);

int main()
{
	enum media_type type = convert("mp3");
	play("helloworld.mp3", type);
	return 0;
}
//增加新类型是记得更新这个表
static char const* types[] = { "mp3", "mp4" };
enum media_type convert(char const* type)
{
	int i = 0;
	for (; i < media_type_cnt; ++i)
	{
		if (strcmp(types[i], type) == 0)
		{
			return (enum media_type)i;
		}
	}
	return unkown_type;
}

void play(char const* fn, enum media_type type)
{
	//...
}
[/quote]
mujiok2003 2013-12-05
  • 打赏
  • 举报
回复
引用 17 楼 zengraoli 的回复:
后来在看了一下代码觉得前面部分,貌似是多余的;而且枚举和int的转换,vs编译不能通过,试过08、10、12、13版本的 昨晚没细看,以为是只用enum类型,原来还是匹配字符串的方式。
1. 不管你用什么方法都避免不了字符串的遍历:使用hash也是从char*->int, map,set等用的就是字符串匹配。 鉴于你的媒体类型不会太多,直接用逐个匹配就好了。 2. 通不过编译的问题,稍加修改就好。

#include <cstring>
enum media_type
{
	mp3,
	mp4,
	media_type_cnt
};
#define unkown_type (enum media_type)-1;

enum media_type convert(char const* type);
void play(char const* fn, enum media_type);

int main()
{
	enum media_type type = convert("mp3");
	play("helloworld.mp3", type);
	return 0;
}
//增加新类型是记得更新这个表
static char const* types[] = { "mp3", "mp4" };
enum media_type convert(char const* type)
{
	int i = 0;
	for (; i < media_type_cnt; ++i)
	{
		if (strcmp(types[i], type) == 0)
		{
			return (enum media_type)i;
		}
	}
	return unkown_type;
}

void play(char const* fn, enum media_type type)
{
	//...
}
  • 打赏
  • 举报
回复
话说这样是不错的,这应该和find比较,和整个串的匹配更快了。外面再加for循环,就行了
引用 16 楼 akirya 的回复:
先根据第一个字母或者2个字母switch case,再strcmp比较。
  • 打赏
  • 举报
回复
后来在看了一下代码觉得前面部分,貌似是多余的;而且枚举和int的转换,vs编译不能通过,试过08、10、12、13版本的 昨晚没细看,以为是只用enum类型,原来还是匹配字符串的方式。
引用 14 楼 mujiok2003 的回复:
[quote=引用 10 楼 zengraoli 的回复:] [quote=引用 7 楼 mujiok2003 的回复:] 就那么几个而已, 直接if-else判断吧。
用if,else以后扩展不好扩,还不如直接find 或者匹配key 然后break呢[/quote] 别轻易下结论。

enum media_type
{
   mp3,
   mp4,
   media_type_cnt
};
#define unkown_type (enum media_type)-1;
enum media_type convert(char const* type);
void play(char const* fn, enum media_type);

int main()
{
  enum media_type type = convert("mp3");
  play("helloworld.mp3",type); 
  return 0;
}
//增加新类型是记得更新这个表
static char const* types[] = {"mp3", "mp4"};
enum media_type convert(char const* type)
{
  enum media_type i = 0;
  for(; i < media_type_cnt; ++i)
  {
     if(strcmp(types[i], type) == 0)
     {
        return i;
     }
  }
  return unkown_type;
}

void play(char const* fn, enum media_type type)
{
   //...
}
[/quote]
  • 打赏
  • 举报
回复
先根据第一个字母或者2个字母switch case,再strcmp比较。
  • 打赏
  • 举报
回复
引用 14 楼 mujiok2003 的回复:
[quote=引用 10 楼 zengraoli 的回复:] [quote=引用 7 楼 mujiok2003 的回复:] 就那么几个而已, 直接if-else判断吧。
用if,else以后扩展不好扩,还不如直接find 或者匹配key 然后break呢[/quote] 别轻易下结论。

enum media_type
{
   mp3,
   mp4,
   media_type_cnt
};
#define unkown_type (enum media_type)-1;
enum media_type convert(char const* type);
void play(char const* fn, enum media_type);

int main()
{
  enum media_type type = convert("mp3");
  play("helloworld.mp3",type); 
  return 0;
}
//增加新类型是记得更新这个表
static char const* types[] = {"mp3", "mp4"};
enum media_type convert(char const* type)
{
  enum media_type i = 0;
  for(; i < media_type_cnt; ++i)
  {
     if(strcmp(types[i], type) == 0)
     {
        return i;
     }
  }
  return unkown_type;
}

void play(char const* fn, enum media_type type)
{
   //...
}
[/quote] 哦 行啊,这种用法我第一次看到,学习啦!
mujiok2003 2013-12-04
  • 打赏
  • 举报
回复
引用 10 楼 zengraoli 的回复:
[quote=引用 7 楼 mujiok2003 的回复:] 就那么几个而已, 直接if-else判断吧。
用if,else以后扩展不好扩,还不如直接find 或者匹配key 然后break呢[/quote] 别轻易下结论。

enum media_type
{
   mp3,
   mp4,
   media_type_cnt
};
#define unkown_type (enum media_type)-1;
enum media_type convert(char const* type);
void play(char const* fn, enum media_type);

int main()
{
  enum media_type type = convert("mp3");
  play("helloworld.mp3",type); 
  return 0;
}
//增加新类型是记得更新这个表
static char const* types[] = {"mp3", "mp4"};
enum media_type convert(char const* type)
{
  enum media_type i = 0;
  for(; i < media_type_cnt; ++i)
  {
     if(strcmp(types[i], type) == 0)
     {
        return i;
     }
  }
  return unkown_type;
}

void play(char const* fn, enum media_type type)
{
   //...
}
  • 打赏
  • 举报
回复
引用 12 楼 unituniverse2 的回复:
貌似可以用hash_map
嗯 可以 我等会试试啊
unituniverse2 2013-12-04
  • 打赏
  • 举报
回复
貌似可以用hash_map
  • 打赏
  • 举报
回复
引用 8 楼 jerry_dqh 的回复:
如果只有这几个,直接比较就可以了。
考虑到扩展就不if-else了
  • 打赏
  • 举报
回复
引用 7 楼 mujiok2003 的回复:
就那么几个而已, 直接if-else判断吧。
用if,else以后扩展不好扩,还不如直接find 或者匹配key 然后break呢
  • 打赏
  • 举报
回复
引用 5 楼 ForestDB 的回复:
map不是有个find方法么? 先用标准库的东西,性能不会太差。
对 有个find,给忘啦 哈哈
碼上道 2013-12-04
  • 打赏
  • 举报
回复
如果只有这几个,直接比较就可以了。
mujiok2003 2013-12-04
  • 打赏
  • 举报
回复
就那么几个而已, 直接if-else判断吧。
ForestDB 2013-12-04
  • 打赏
  • 举报
回复
先功能,后性能。
ForestDB 2013-12-04
  • 打赏
  • 举报
回复
map不是有个find方法么? 先用标准库的东西,性能不会太差。
  • 打赏
  • 举报
回复
引用 3 楼 ForestDB 的回复:
LZ怎就觉得用map和set会慢呢?
已经是我想到的最快的方法了,但是map不是还得迭代器进行key值的匹配么? 你说的set不好懂啊?
ForestDB 2013-12-04
  • 打赏
  • 举报
回复
LZ怎就觉得用map和set会慢呢?
  • 打赏
  • 举报
回复
引用 1 楼 ForestDB 的回复:
C++的map和set底下其实是一样的。
那样更快速的方法有么?
ForestDB 2013-12-04
  • 打赏
  • 举报
回复
C++的map和set底下其实是一样的。
学习并掌握C++2.0(11+14+17+20)的新特性,学习线程及线程池的应用 ---------------------------------------------------给小白学员的3年学习路径及计划技术方面分三块:1.纯开发技术方向2.音视频流媒体专业方向3.项目实战---------------------------------------------------1.纯开发技术方向(1) C++必须要过硬(至少学会10本经典好书)(2) 系统级编程(Windows、Linux),必须特别熟练系统API,灵活运用(3) 框架与工具(Qt、MFC):必须精通其中一种。(4) 架构与设计模式:需要提升一个高度,不再是简单的编码,而是思维模式。(5) 驱动级别(如果有兴趣,可以深入到驱动级:包括Windows、Linux)(6) 最好学习点Java+Html+javascript等WEB技术。2.音视频流媒体专业方向(1) 音视频流媒体基础理论:   必须认真学会,否则看代码就是看天书(2) 编解码方向:精通h.264,h.265(hevc), 包括理论和各个开源库(ffmpeg,libx264,libx265,...)。(3) 直播方向:  精通各种直播协议(rtsp,rtmp,hls,http-flv,...), 钻研各个开源库(live555,darwin,srs,zlmediakit,crtmpserver,...)(4) 视频监控:  理论+开源库(onvif+281818)(EasyMonitor、iSpy、ZoneMinder(web)、...) 3.项目实战(1) Qt项目:  至少要亲手练习10个实战项目(网络服务器、多线程、数据库、图像处理、多人聊天、等等)(2)音视频项目:包括编解码、视频监控、直播等各个方向,都需要亲手实战项目,包括视频服务器、后台管理系统、前端播放器(多端)---------------------------------------------------  第1章 C++11新特性 41). nullptr关键字与新语法 42). auto和decltype类型推导 6 auto讲解 6 auto示例 7 decltype 83). for区间迭代 94). 初始化列表 105). 模板增强 11外部模板 11类型别名模板 12默认模板参数 126). 构造函数 13委托构造 13继承构造 147). Lambda 表达式 158). 新增容器 20std::array 20std::forward_list 21无序容器 22元组 std::tuple 239). 正则表达式 2610). 语言级线程支持 28多线程库简介 2811). 右值引用和move语义 31右值引用和move语义 32转移左值 3412). constexpr 35第2章 C++14新特性 36Lambda 函数 36类型推导 37返回值类型推导(Return type deduction) 37泛型lambda 39[[弃用的]]  [[deprecated]]属性 40二进制数字和数字分隔符 41第3章 C++17新特性 42安装GCC10.2 42安装msys2-x86_64-20200720 42更新镜像 42更新软件库 43安装 MinGW64 等必要的软件 43环境变量Path 43编译命令 43constexpr 44typename 45折叠表达式 47结构化绑定 48条件分支语句初始化 49聚合初始化 50嵌套命名空间 52lambda表达式捕获*this的值 53改写/继承构造函数 54用auto作为非类型模板参数 55__has_include 56fallthrough 57nodiscard 57maybe_unused 58第4章 C++20新特性 59编译命令 59concept 59typename 60explicit 61constinit 62位域变量的默认成员初始化 62指定初始化 63基于范围的for循环初始化 64放宽基于范围的for循环,新增自定义范围方法 65嵌套内联命名空间 66允许用圆括弧的值进行聚合初始化 67unicode字符串字面量 68允许转换成未知边界的数组 68likely和unlikely 69第5章 C++2.0(11/14/17/20)总结与分析 705.1 C语言与C++ 715.2 语言可用性的强化 725.2.1 常量 725.2.2 变量及其初始化 735.2.3 类型推导 745.2.4 控制流 765.2.5 模板 775.2.6 面向对象 815.3 语言运行期的强化 835.3.1 Lambda 表达式 835.3.2 右值引用 865.4 容器 885.4.1 线性容器 885.4.2 无序容器 895.4.3 元组 895.5 智能指针与内存管理 905.5.1 RAII 与引用计数 905.5.2 std::shared_ptr 905.5.3 std::unique_ptr 915.5.4 std::weak_ptr 91第6章 C++2.0多线程原理与实战 93什么是并发 93并发的方式 93为什么使用并发 95线程简介 96创建线程的三种方式 971. 通过函数 972.通过类对象创建线程 993.通过lambda表达式创建线程 101thread线程的使用 101互斥量与临界区 105期物Future 111条件变量 112原子操作 114内存模型 118第7章 C++2.0线程池原理与实战 120线程与线程池的基本原理 1201)、线程 1202)、线程的生命周期 1213)、什么是单线程和多线程 1214)、线程池 1225)、四种常见的线程池 123线程池的架构与流程 123线程池代码实战 125    

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧