如何将一个字符串进行反过来输出

本文介绍了如何使用StringBuffer来处理字符串,包括定义字符串、将其添加到StringBuffer中以及遍历输出等基本操作。此外还提到了一种通过循环遍历并输出StringBuffer中元素的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



第一步:我们定义一个字符串。

第二步:然后将这个变量放入到StringBuffer中。

第三步:循环遍历StringBuffer,然后将对应下标的值进行输出。

备注:如果想使用快速方法,我们可以直接调用StringBuffer中的反转方法,如果要有逻辑进行可以尝试使用我这种方法。

<think>我们有一个枚举类型CaptureImageSize,现在需要将给定的分辨率字符串(如"1280x720")转换为对应的枚举值(如CAPTURE_IMAGE_SIZE_720P)。 注意:枚举中有些分辨率有多个制式(如PAL和NTSC),但我们在转换时只需匹配宽高数字,忽略制式说明。另外,有些枚举值对应多个分辨率(如4K有两种),但我们在转换时只需要匹配数字部分。 步骤: 1. 解析输入字符串,提取宽度和高度数字。 2. 遍历枚举值对应的分辨率字符串(或预先建立的映射表),找到匹配的枚举值。 但是,枚举定义中有些分辨率在字符串中包含了多种制式(如D1:704*576(PAL)和704*480(NTSC)),我们只需要匹配数字部分,即“704*576”或“704*480”都可以匹配到CAPTURE_IMAGE_SIZE_D1。 然而,枚举中有些条目是单一分辨率(如VGA:640*480),有些是多个(如D1)。因此,我们需要为每个枚举值建立一组可能的数字分辨率字符串(去掉制式说明)的集合。 注意:枚举值中有些是纯数字,有些包含了乘号(×或*),在匹配时我们需要统一处理。 另外,枚举中有一些重复的尺寸(例如,CAPTURE_IMAGE_SIZE_5M和CAPTURE_IMAGE_SIZE_5M_N都是1872*1408),但它们是不同的枚举值。因此,我们需要根据实际需求决定如何区分,或者按照枚举定义分别对应。 但是,用户输入的分辨率字符串可能没有制式信息,比如用户输入"704*576"或"704x576",我们都应该匹配到D1。 设计: 1. 我们可以构建一个从分辨率字符串(规范化为"宽x高"或"宽*高")到枚举值的映射表。注意,一个枚举值可能对应多个分辨率字符串(如D1对应两个),那么映射表中每个分辨率字符串都映射到同一个枚举值。 2. 规范化用户输入:将用户输入的字符串中的乘号(可能是'x','X','*','×'等)统一替换为一个标准符号(比如'*'),然后分割出宽度和高度,再重新组合成标准字符串(比如"宽*高")。 3. 在映射表中查找这个字符串,如果找到则返回对应的枚举值;否则,尝试另一种组合(比如用户输入的是"高度x宽度",但我们的映射表是"宽度x高度",这种情况通常不需要,因为分辨率都是宽度在前)?注意,一般情况下分辨率都是宽度在前。 但是,枚举中有些尺寸的表示使用了不同的符号(如×和*),例如: CAPTURE_IMAGE_SIZE_6M: "3072×2048" CAPTURE_IMAGE_SIZE_8M: "3264×2448" 我们需要在构建映射表时统一使用一个符号(比如'*'),将枚举中的分辨率字符串中的乘号也替换为这个符号。 另外,枚举中有些分辨率有多个表示(如4K:4096*2160/3840*2160),我们需要拆分成两个字符串:4096*2160和3840*2160,都映射到CAPTURE_IMAGE_SIZE_4K。 因此,我们需要为每个枚举值生成一个或多个分辨率字符串(只包含数字和乘号),建立映射。 特殊枚举值: - 跳过计数枚举值(如NR, EXT_NR, EXT_V3_NR等) - 注意:枚举中有些枚举值被赋予了相同的数值(如CAPTURE_IMAGE_SIZE_NR和CAPTURE_IMAGE_SIZE_ND1都是9),但它们是不同的枚举常量,我们只需要处理有实际分辨率意义的枚举常量。 具体步骤: 1. 创建一个映射表(std::map或std::unordered_map),键为规范化的分辨率字符串(如"1280*720"),值为枚举值。 2. 遍历枚举中每个有实际分辨率定义的项(跳过计数项),将每个项的分辨率字符串解析成一个或多个规范化字符串(用'*'连接宽高),然后插入到映射表中(注意:同一个枚举值可能有多个键)。 3. 处理用户输入:去除空格,将'x','X','×'等替换为'*',然后尝试在映射表中查找。 4. 如果找到,返回枚举值;否则,返回一个错误(如抛出异常或返回一个表示未知的枚举值)。 枚举值列表(只取有实际分辨率的)及其对应的分辨率字符串(我们将其拆分成多个规范化字符串): CAPTURE_IMAGE_SIZE_D1: ["704*576", "704*480"] CAPTURE_IMAGE_SIZE_HD1: ["704*288", "704*240"] CAPTURE_IMAGE_SIZE_BCIF: ["352*576", "352*480"] CAPTURE_IMAGE_SIZE_CIF: ["352*288", "352*240"] CAPTURE_IMAGE_SIZE_QCIF: ["176*144", "176*120"] CAPTURE_IMAGE_SIZE_VGA: ["640*480"] CAPTURE_IMAGE_SIZE_QVGA: ["320*240"] CAPTURE_IMAGE_SIZE_SVCD: ["480*480"] CAPTURE_IMAGE_SIZE_QQVGA: ["160*128"] CAPTURE_IMAGE_SIZE_ND1: ["240*192"] CAPTURE_IMAGE_SIZE_650TVL: ["926*576"] CAPTURE_IMAGE_SIZE_720P: ["1280*720"] CAPTURE_IMAGE_SIZE_1_3M: ["1280*960"] CAPTURE_IMAGE_SIZE_UXGA: ["1600*1200"] CAPTURE_IMAGE_SIZE_1080P: ["1920*1080"] CAPTURE_IMAGE_SIZE_WUXGA: ["1920*1200"] CAPTURE_IMAGE_SIZE_2_5M: ["1872*1408"] CAPTURE_IMAGE_SIZE_3M: ["2048*1536"] CAPTURE_IMAGE_SIZE_5M: ["3744*1408"] CAPTURE_IMAGE_SIZE_1080N: ["960*1080"] CAPTURE_IMAGE_SIZE_4M: ["2592*1520"] CAPTURE_IMAGE_SIZE_6M: ["3072*2048"] // 注意原字符串是×,替换为* CAPTURE_IMAGE_SIZE_8M: ["3264*2448"] // 同上 CAPTURE_IMAGE_SIZE_12M: ["4000*3000"] CAPTURE_IMAGE_SIZE_4K: ["4096*2160", "3840*2160"] CAPTURE_IMAGE_SIZE_720N: ["640*720"] CAPTURE_IMAGE_SIZE_WSVGA: ["1024*576"] CAPTURE_IMAGE_SIZE_NHD: ["640*360"] CAPTURE_IMAGE_SIZE_3M_N: ["1024*1536"] CAPTURE_IMAGE_SIZE_4M_N: ["1296*1520"] CAPTURE_IMAGE_SIZE_5M_N: ["1872*1408"] // 注意:与CAPTURE_IMAGE_SIZE_2_5M相同,但枚举值不同,所以需要分别映射 CAPTURE_IMAGE_SIZE_4K_N: ["2048*2160", "1920*2160"] 注意:CAPTURE_IMAGE_SIZE_5M和CAPTURE_IMAGE_SIZE_5M_N都是1872*1408?但是枚举中CAPTURE_IMAGE_SIZE_5M是3744*1408,而CAPTURE_IMAGE_SIZE_5M_N是1872*1408。所以不会重复。 但是,CAPTURE_IMAGE_SIZE_2_5M是1872*1408,而CAPTURE_IMAGE_SIZE_5M_N也是1872*1408。这两个枚举值对应相同的分辨率字符串。因此,在映射表中,同一个分辨率字符串将对应两个枚举值?这不行,因为键是唯一的。 问题:同一个分辨率可能对应多个枚举值?我们需要根据上下文区分吗?但用户输入一个分辨率字符串,我们无法知道是指哪个枚举值。因此,我们需要设计一个策略: 方案1:不允许重复的分辨率字符串。但枚举中确实出现了重复(如2_5M和5M_N都是1872*1408)。这可能是枚举定义的问题,或者实际应用中它们代表不同的含义(比如不同的传感器模式)。但我们的转换函数无法区分,所以只能选择一个(比如按照枚举值顺序选择第一个出现的,或者按照枚举值的大小选择第一个?)。 方案2:在映射表中,同一个分辨率字符串映射到多个枚举值?但这样函数返回就不唯一了。 方案3:在构建映射表时,如果遇到重复,则只保留一个(比如保留先出现的那个)。但这样会丢失信息。 方案4:在枚举定义中,这些重复的分辨率字符串实际上对应不同的枚举值,但我们的转换函数无法通过分辨率字符串区分它们,因此我们只能返回一个错误(当出现重复时,要求用户使用其他方式指定,或者返回一个错误值)。但这样不友好。 重新检查枚举定义: CAPTURE_IMAGE_SIZE_2_5M = 17, ///< 1872*1408 ... CAPTURE_IMAGE_SIZE_5M_N = 32, //< 1872*1408 因此,同一个分辨率字符串"1872*1408"对应两个枚举值:CAPTURE_IMAGE_SIZE_2_5M和CAPTURE_IMAGE_SIZE_5M_N。 如何解决? 由于转换函数无法通过字符串区分这两个枚举值,因此我们只能选择其中一个。但这样会丢失信息。 考虑到实际使用中,用户可能期望的是其中一个(比如2_5M是标准定义,而5M_N是某种特殊模式),我们可能需要根据实际系统设计来决定。但这里没有上下文,我们可以按照枚举值出现的顺序(数值大小)选择较小的那个(即CAPTURE_IMAGE_SIZE_2_5M,因为它的枚举值17比32小)?或者按照枚举定义中的顺序(先定义2_5M,后定义5M_N)? 但是,枚举值的大小不代表顺序(因为枚举值可以赋值,而这里2_5M=17, 5M_N=32,所以17<32),所以我们可以选择数值较小的那个(即先定义的)?但枚举定义中2_5M确实在5M_N之前。 然而,这不合理,因为用户可能期望的是5M_N。所以,我们需要避免这种歧义。 实际上,在枚举定义中,5M_N的注释中明确写了“通用”或“海思”,所以它们可能是针对不同平台的。但在转换函数中,我们无法知道平台。 因此,我们可能需要修改需求:转换函数不支持有歧义的分辨率字符串。当出现歧义时,我们返回错误(比如抛出异常,或者返回一个特定的错误枚举值)。 但是,我们也可以要求用户输入时指定平台或其他信息?这超出了当前函数的范围。 权衡后,我们决定:在映射表中,如果同一个分辨率字符串已经存在,则记录一个错误(比如记录到日志),然后跳过后续的重复项。这样,当用户输入这个分辨率字符串时,我们返回的是先出现的枚举值。同时,我们在文档中说明:如果存在重复的分辨率字符串,则返回第一个匹配的枚举值。 另一种做法:在构建映射表时,如果遇到重复,则将该键删除(即该分辨率字符串不映射到任何枚举值)。这样当用户输入这个字符串时,我们返回错误(未知分辨率)。但这样会导致这两个枚举值都无法通过字符串转换。 考虑到实际使用中,用户可能更常用的是2_5M,而5M_N可能是特定平台,我们可以暂时将5M_N的分辨率字符串映射到5M_N,但这样就会覆盖2_5M。所以不行。 因此,我们只能保留一个。我们决定保留先出现的枚举值(即枚举值数值较小的那个)。所以对于"1872*1408",我们只保留CAPTURE_IMAGE_SIZE_2_5M(枚举值17)。 但是,CAPTURE_IMAGE_SIZE_5M_N的注释中说明是“1872*1408”,我们也可以将其映射到5M_N,但这样就会覆盖2_5M。所以我们需要在构建映射表时,先添加枚举值小的,当遇到重复时,不添加后面的重复项。这样,2_5M会先被添加,5M_N的相同字符串就不会添加了。那么5M_N就无法通过这个字符串转换。 或者,我们可以为5M_N添加一个不同的键?但它的分辨率字符串就是1872*1408,没有其他表示。 所以,我们只能牺牲5M_N的转换。或者,在5M_N的键上加上后缀?比如"1872*1408(N)",但这样用户输入时也要带后缀,不符合要求。 结论:暂时先按保留第一个出现的枚举值来处理。如果用户需要转换5M_N,则必须使用其他方式(比如直接使用枚举值)。或者,我们提供另一个函数,可以指定平台来转换。 由于问题中没有提到平台区分,我们先按简单处理:保留第一个出现的枚举值。 实现步骤: 1. 创建一个映射表:std::unordered_map<std::string, CaptureImageSize> resolutionMap; 2. 按枚举值从小到大的顺序(即枚举定义的顺序)遍历每个有实际分辨率的枚举常量,对于每个枚举常量,将其对应的分辨率字符串(可能有多个)逐个处理: a. 将字符串中的非数字字符(除了乘号)去除,但这里我们的字符串已经是数字和乘号(或×)了。 b. 将字符串中的'×'替换为'*',然后分割字符串,提取出宽度和高度(注意:有些字符串可能有多个分辨率,用斜杠分隔,如4K)。 c. 对于每个用斜杠分隔的分辨率,单独处理(拆分成多个字符串)。 d. 将每个拆分后的字符串规范化(去除空格,确保宽高顺序,组合成"宽*高"的字符串)。 e. 检查这个规范化字符串是否已经在映射表中,如果已经存在,则跳过(不覆盖,因为我们要保留先出现的)。 f. 如果不存在,则添加到映射表中。 但是,枚举值的顺序不是数值顺序,而是定义顺序(在C++枚举中,如果没有指定数值,则按定义顺序从0开始递增,但这里有些指定了数值)。我们遍历的顺序应该按照枚举值数值从小到大的顺序?但枚举定义中有些后定义的枚举值数值小(比如CAPTURE_IMAGE_SIZE_ND1=9,而CAPTURE_IMAGE_SIZE_650TVL=10,所以数值顺序就是定义顺序)。 因此,我们可以按枚举值数值顺序遍历(从0到最大值)。但枚举定义中,枚举值不是连续的(比如从0到25,然后跳到19,然后又到25,再到26...)。而且,有些枚举值(计数用的)我们没有实际分辨率。 所以,我们改为按枚举定义中出现的顺序(即代码中的顺序)来遍历,且跳过计数枚举值。 我们可以手动列出有实际分辨率的枚举常量(按照定义顺序): CAPTURE_IMAGE_SIZE_D1, // 0 CAPTURE_IMAGE_SIZE_HD1, // 1 CAPTURE_IMAGE_SIZE_BCIF, // 2 CAPTURE_IMAGE_SIZE_CIF, // 3 CAPTURE_IMAGE_SIZE_QCIF, // 4 CAPTURE_IMAGE_SIZE_VGA, // 5 CAPTURE_IMAGE_SIZE_QVGA, // 6 CAPTURE_IMAGE_SIZE_SVCD, // 7 CAPTURE_IMAGE_SIZE_QQVGA, // 8 // 跳过 CAPTURE_IMAGE_SIZE_NR = 9 (计数,跳过) CAPTURE_IMAGE_SIZE_ND1 = 9, // 9 -> 注意,这里和NR相同数值,但它是实际分辨率 CAPTURE_IMAGE_SIZE_650TVL, // 10 CAPTURE_IMAGE_SIZE_720P, // 11 CAPTURE_IMAGE_SIZE_1_3M, // 12 CAPTURE_IMAGE_SIZE_UXGA, // 13 CAPTURE_IMAGE_SIZE_1080P, // 14 CAPTURE_IMAGE_SIZE_WUXGA, // 15 CAPTURE_IMAGE_SIZE_2_5M, // 16 CAPTURE_IMAGE_SIZE_3M, // 17 CAPTURE_IMAGE_SIZE_5M, // 18 // 跳过 CAPTURE_IMAGE_SIZE_EXT_NR = 19 (计数) CAPTURE_IMAGE_SIZE_1080N = 19, // 19 CAPTURE_IMAGE_SIZE_4M, // 20 CAPTURE_IMAGE_SIZE_6M, // 21 CAPTURE_IMAGE_SIZE_8M, // 22 CAPTURE_IMAGE_SIZE_12M, // 23 CAPTURE_IMAGE_SIZE_4K, // 24 // 跳过 CAPTURE_IMAGE_SIZE_EXT_V2_NR =25 (计数) CAPTURE_IMAGE_SIZE_720N = 25, // 25 CAPTURE_IMAGE_SIZE_WSVGA, // 26 CAPTURE_IMAGE_SIZE_NHD, // 27 CAPTURE_IMAGE_SIZE_3M_N, // 28 CAPTURE_IMAGE_SIZE_4M_N, // 29 CAPTURE_IMAGE_SIZE_5M_N, // 30 CAPTURE_IMAGE_SIZE_4K_N, // 31 // 跳过 CAPTURE_IMAGE_SIZE_EXT_V3_NR // 32(这个没有指定数值?在枚举中最后一个,所以应该是32) 注意:枚举值相同的项(如NR和ND1都是9)在枚举类型中是不同的常量,但它们的数值相同。在switch-case中,它们会进入同一个case。所以我们在遍历时,只能取其中一个(按照定义顺序,先定义的是NR,然后是ND1)。但NR是计数,我们跳过,所以我们取ND1(因为它有实际分辨率)。 因此,我们按数值顺序从0到32(最大值)遍历,但只处理有实际分辨率的项,且跳过计数项。 但是,枚举值相同的情况下,我们无法通过数值来区分不同的常量(因为它们是同一个数值)。所以,我们只能按定义顺序,且只处理一次每个数值(如果同一个数值有多个常量,我们只取第一个有实际分辨率的那个)。 具体做法:我们创建一个数组,按枚举值数值作为索引,存储对应的分辨率字符串集合(如果有多个常量对应同一个数值,我们只存储第一个有实际分辨率的那个,忽略后面的?或者存储最后一个?)。但这里,我们按照定义顺序,当遇到一个数值时,如果已经处理过这个数值,则跳过。 由于枚举定义中,同一个数值的多个常量是连续定义的,我们可以这样处理: 但是,我们的枚举定义中,同一个数值的常量(如9)有两个:NR和ND1,我们只想处理ND1(因为NR是计数,而ND1有实际分辨率)。所以,我们在处理数值9时,应该使用ND1,而不是NR。 因此,我们需要根据常量名称来判断?这样就不通用了。 所以,我们改为手动构建一个列表,只包含有实际分辨率的枚举常量(按定义顺序)及其对应的分辨率字符串。 我们手动列出(如上所示),然后按这个列表的顺序构建映射表。 为了代码可维护性,我们可以使用一个静态的向量,每个元素是一个结构体,包含枚举值和对应的原始字符串。然后按顺序处理。 代码实现: 由于枚举值较多,我们使用一个辅助函数来初始化映射表。 注意:枚举值中有些分辨率字符串包含非数字字符(如PAL/NTSC说明),我们需要过滤掉这些字符,只保留数字和乘号(或×)。然后拆分成多个分辨率。 具体步骤: 初始化映射表函数: std::unordered_map<std::string, CaptureImageSize> createResolutionMap() { std::unordered_map<std::string, CaptureImageSize> map; // 按顺序添加枚举值及其分辨率字符串(原始字符串) std::vector<std::pair<CaptureImageSize, std::string>> enumResolutions = { {CAPTURE_IMAGE_SIZE_D1, "704*576(PAL) 704*480(NTSC)"}, {CAPTURE_IMAGE_SIZE_HD1, "704*288(PAL) 704*240(NTSC)"}, ... // 其他项 }; for (const auto& item : enumResolutions) { // 处理原始字符串:按空格分割,然后每个部分再提取数字和乘号(或×) // 但是,原始字符串中可能用空格分隔了多个分辨率,每个分辨率包含数字和乘号以及制式说明。 // 我们可以用空格分割,然后过滤掉空字符串,然后对每个子字符串提取数字和乘号(或×) std::string raw = item.second; // 分割raw std::vector<std::string> parts; // 简单的空格分割(可能有多个空格) // 使用字符串流分割 std::istringstream iss(raw); std::string part; while (iss >> part) { if (!part.empty()) { parts.push_back(part); } } // 现在parts的每个元素可能是"704*576(PAL)"这样的字符串 for (auto& p : parts) { // 提取分辨率部分:从开始到第一个非数字非乘号(非'*'和'×')之前 // 或者,我们只保留数字和'*','×',其他都去掉 std::string clean; for (char c : p) { if (isdigit(c) || c=='*' || c=='×') { clean += c; } } // 现在clean是类似"704*576"的字符串,但可能中间是'×',我们统一替换为'*' std::replace(clean.begin(), clean.end(), '×', '*'); // 检查clean是否为空 if (clean.empty()) continue; // 检查clean中是否包含'*',如果不包含,则不是有效的分辨率字符串,跳过。 if (clean.find('*') == std::string::npos) { continue; } // 现在clean是规范化的字符串,如"704*576" // 检查映射表中是否已有这个字符串,如果有,则跳过(不添加,保留先出现的) if (map.find(clean) == map.end()) { map[clean] = item.first; } // 否则,已经存在,跳过(保留先出现的) } } return map; } 但是,有些枚举项的分辨率字符串不是用空格分隔多个分辨率,而是用斜杠,如: CAPTURE_IMAGE_SIZE_4K: return "4096*2160/3840*2160" 所以,我们还需要处理斜杠。 因此,在分割原始字符串时,除了空格,还要考虑斜杠(和可能的分隔符)。我们可以先替换斜杠为空格,然后再分割。 修改:在原始字符串处理时,将可能的分隔符(如'/', '、'等)替换为空格,然后用空格分割。 另外,有些项只有一个分辨率,没有制式说明(如VGA:640*480),所以我们的处理是通用的。 但是,枚举项CAPTURE_IMAGE_SIZE_5M_N: "1872*1408",只有一个,没有制式。 所以,我们修改原始字符串处理:将非数字非乘号非分隔符的字符先替换为空格?或者直接按上述方法提取每个连续的数字和乘号序列?但这样会丢失分隔符信息。 我们换一种方法:我们不需要制式信息,所以可以删除括号内的内容,然后再分割。 例如:对于"704*576(PAL)",我们删除括号及其内容,变成"704*576"。 所以,我们可以这样做: // 删除括号及其内容 std::string removeParentheses(const std::string& s) { std::string result; bool inParentheses = false; for (char c : s) { if (c == '(') { inParentheses = true; } else if (c == ')') { inParentheses = false; } else if (!inParentheses) { result += c; } } return result; } 然后,将原始字符串应用这个函数,得到的结果就是去除了括号内容的字符串。然后,这个字符串中可能包含多个分辨率,用空格或斜杠分隔。我们再用空格和斜杠作为分隔符来分割。 但是,斜杠可能出现在两个分辨率之间,如"4096*2160/3840*2160",我们将其替换为空格,然后分割。 所以,步骤: raw = removeParentheses(raw); // 去除括号内容 // 替换斜杠为空格 std::replace(raw.begin(), raw.end(), '/', ' '); // 然后按空格分割 这样,处理后的raw字符串中,多个分辨率用空格分隔。 然后,分割后每个部分就是一个分辨率字符串(只包含数字和乘号),然后我们将其中的'×'替换为'*',然后检查是否包含'*',如果包含,则作为键。 注意:有些分辨率字符串可能没有乘号?不可能,因为我们定义中都有。 最后,构建映射表。 但是,有些枚举项的分辨率字符串中使用了'×'(如6M和8M),我们已经在替换中统一为'*'了。 现在,我们编写代码: 由于枚举值较多,我们使用一个列表来初始化enumResolutions。注意,我们只列出有实际分辨率的枚举项,按照定义顺序。 注意:枚举项CAPTURE_IMAGE_SIZE_ND1的分辨率字符串是"240*192",没有制式说明。 我们手动列出所有有实际分辨率的枚举项及其原始字符串(从枚举的注释中获取): {CAPTURE_IMAGE_SIZE_D1, "704*576(PAL) 704*480(NTSC)"}, {CAPTURE_IMAGE_SIZE_HD1, "704*288(PAL) 704*240(NTSC)"}, {CAPTURE_IMAGE_SIZE_BCIF, "352*576(PAL) 352*480(NTSC)"}, {CAPTURE_IMAGE_SIZE_CIF, "352*288(PAL) 352*240(NTSC)"}, {CAPTURE_IMAGE_SIZE_QCIF, "176*144(PAL) 176*120(NTSC)"}, {CAPTURE_IMAGE_SIZE_VGA, "640*480"}, // 注意:原始注释是"640*480(PAL) 640*480(NTSC)"?但实际注释没有,所以写"640*480" {CAPTURE_IMAGE_SIZE_QVGA, "320*240"}, {CAPTURE_IMAGE_SIZE_SVCD, "480*480"}, {CAPTURE_IMAGE_SIZE_QQVGA, "160*128"}, {CAPTURE_IMAGE_SIZE_ND1, "240*192"}, {CAPTURE_IMAGE_SIZE_650TVL, "926*576"}, {CAPTURE_IMAGE_SIZE_720P, "1280*720"}, {CAPTURE_IMAGE_SIZE_1_3M, "1280*960"}, {CAPTURE_IMAGE_SIZE_UXGA, "1600*1200"}, {CAPTURE_IMAGE_SIZE_1080P, "1920*1080"}, {CAPTURE_IMAGE_SIZE_WUXGA, "1920*1200"}, {CAPTURE_IMAGE_SIZE_2_5M, "1872*1408"}, {CAPTURE_IMAGE_SIZE_3M, "2048*1536"}, {CAPTURE_IMAGE_SIZE_5M, "3744*1408"}, {CAPTURE_IMAGE_SIZE_1080N, "960*1080"}, {CAPTURE_IMAGE_SIZE_4M, "2592*1520"}, {CAPTURE_IMAGE_SIZE_6M, "3072×2048"}, // 注意这里是× {CAPTURE_IMAGE_SIZE_8M, "3264×2448"}, {CAPTURE_IMAGE_SIZE_12M, "4000*3000"}, {CAPTURE_IMAGE_SIZE_4K, "4096 * 2160/3840*2160"}, // 注意空格和斜杠 {CAPTURE_IMAGE_SIZE_720N, "640*720"}, {CAPTURE_IMAGE_SIZE_WSVGA, "1024*576"}, {CAPTURE_IMAGE_SIZE_NHD, "640*360"}, {CAPTURE_IMAGE_SIZE_3M_N, "1024*1536"}, {CAPTURE_IMAGE_SIZE_4M_N, "1296*1520"}, {CAPTURE_IMAGE_SIZE_5M_N, "1872*1408"}, {CAPTURE_IMAGE_SIZE_4K_N, "2048 * 2160/1920*2160"}, 注意:有些分辨率字符串中有空格(如4K的"4096 * 2160"),我们在去除括号内容后,需要将空格删除?或者不去除,因为我们在分割时是按空格分割的,所以分割后会有"4096"和"*"和"2160"?这样不行。 所以,在去除括号内容后,我们还要删除所有空格,然后再替换斜杠为空格,再分割?不行,因为删除空格后,4096*2160会变成4096*2160(没有空格),而3840*2160也是,所以整个字符串变成"4096*21603840*2160",这不行。 因此,我们保留空格,但在分割之前,将空格作为分隔符(字符串流默认以空格分隔),这样分割后,每个部分应该是连续的非空格字符串。而"4096*2160"是一个字符串(因为中间没有空格?但原字符串中有空格:4096 * 2160,所以分割后会是三个部分:"4096", "*", "2160"),这不行。 所以,我们需要在去除括号内容后,将字符串中的空格都删除,这样"4096 * 2160"就变成"4096*2160"(如果删除空格)?不对,删除空格后变成"4096*2160"。 因此,我们在去除括号内容后,删除字符串中的所有空格,然后将斜杠替换为空格(用于分割),然后再分割。 步骤: raw = removeParentheses(raw); // 去除括号内容 // 删除所有空格 raw.erase(std::remove_if(raw.begin(), raw.end(), ::isspace), raw.end()); // 替换斜杠为空格 std::replace(raw.begin(), raw.end(), '/', ' '); // 然后分割 这样,原始字符串"4096 * 2160/3840*2160" 变成 "4096*2160 3840*2160"(删除空格后为"4096*2160/3840*2160",然后替换斜杠为空格,变成"4096*2160 3840*2160"),分割后得到两个字符串:"4096*2160"和"3840*2160"。 完美。 现在,我们编写函数: 由于代码较长,我们将其分为几个辅助函数。 最终,我们有一个全局的映射表(静态变量),在第一次调用转换函数时初始化。 转换函数: CaptureImageSize stringToCaptureImageSize(const std::string& resolutionStr) { static const std::unordered_map<std::string, CaptureImageSize> resolutionMap = createResolutionMap(); // 规范化用户输入 std::string user = resolutionStr; // 删除用户输入中的空格 user.erase(std::remove_if(user.begin(), user.end(), ::isspace), user.end()); // 将用户输入中的'x','X','×'替换为'*' std::replace(user.begin(), user.end(), 'x', '*'); std::replace(user.begin(), user.end(), 'X', '*'); std::replace(user.begin(), user.end(), '×', '*'); // 现在user是类似"1280*720"的字符串 auto it = resolutionMap.find(user); if (it != resolutionMap.end()) { return it->second; } // 没有找到,尝试另一种可能:用户输入可能是高度在前?但一般不会,所以我们返回错误 throw std::invalid_argument("Unsupported resolution string"); } 注意:这个函数可能抛出异常,调用者需要捕获。 另外,我们也可以考虑不抛出异常,而是返回一个特定的枚举值(如CAPTURE_IMAGE_SIZE_NR,但它是计数,不合适)。或者,我们可以定义一个表示错误的枚举值(但枚举中没有)。所以,我们选择抛出异常。 最后,我们还需要考虑用户输入的分辨率字符串中的数字可能有前导零?比如"0640*0480",但这种情况很少,我们不做处理。如果出现,就会匹配失败。所以,用户输入应该和枚举中定义的一致(没有前导零)。 如果枚举中定义有前导零,那我们在构建映射表时也删除了空格,所以不会有前导零(因为数字前面的空格被删除了,但数字内部的前导零不会被删除)。所以,我们构建的映射表中键是没有空格的,用户输入我们也删除了空格,所以只要数字一致就能匹配。 但是,枚举中定义的数字都是没有前导零的,所以用户输入也不应该有前导零。 现在,我们编写完整的代码。 注意:由于枚举值较多,且createResolutionMap函数较长,我们将其实现为静态函数。 由于代码较长,这里只给出关键部分。 考虑到代码量,我们可能需要在头文件中声明函数,在cpp文件中实现映射表。 但是,这里我们给出完整示例。 注意:枚举类型的定义我们假设已经存在。 代码示例:</think>### 分辨率字符串到枚举值的转换实现 根据需求,需要将分辨率字符串(如 "1280x720")转换为对应的 `CaptureImageSize` 枚举值(如 `CAPTURE_IMAGE_SIZE_720P`)。以下是完整的转换方案: #### 转换函数实现(C++) ```cpp #include <string> #include <unordered_map> #include <algorithm> #include <stdexcept> CaptureImageSize stringToCaptureImageSize(const std::string& resolutionStr) { // 规范化输入字符串:移除空格,统一小写 std::string normalized = resolutionStr; normalized.erase(std::remove_if(normalized.begin(), normalized.end(), ::isspace), normalized.end()); std::transform(normalized.begin(), normalized.end(), normalized.begin(), ::tolower); // 替换分隔符为统一格式(支持 x/X/*) size_t pos; while ((pos = normalized.find_first_of("x*×")) != std::string::npos) { normalized.replace(pos, 1, "x"); } // 分辨率到枚举值的映射表 static const std::unordered_map<std::string, CaptureImageSize> resolutionMap = { {"704x576", CAPTURE_IMAGE_SIZE_D1}, // 兼容 PAL {"704x480", CAPTURE_IMAGE_SIZE_D1}, // 兼容 NTSC {"704x288", CAPTURE_IMAGE_SIZE_HD1}, {"704x240", CAPTURE_IMAGE_SIZE_HD1}, {"352x576", CAPTURE_IMAGE_SIZE_BCIF}, {"352x480", CAPTURE_IMAGE_SIZE_BCIF}, {"352x288", CAPTURE_IMAGE_SIZE_CIF}, {"352x240", CAPTURE_IMAGE_SIZE_CIF}, {"176x144", CAPTURE_IMAGE_SIZE_QCIF}, {"176x120", CAPTURE_IMAGE_SIZE_QCIF}, {"640x480", CAPTURE_IMAGE_SIZE_VGA}, {"320x240", CAPTURE_IMAGE_SIZE_QVGA}, {"480x480", CAPTURE_IMAGE_SIZE_SVCD}, {"160x128", CAPTURE_IMAGE_SIZE_QQVGA}, {"240x192", CAPTURE_IMAGE_SIZE_ND1}, {"926x576", CAPTURE_IMAGE_SIZE_650TVL}, {"1280x720", CAPTURE_IMAGE_SIZE_720P}, {"1280x960", CAPTURE_IMAGE_SIZE_1_3M}, {"1600x1200", CAPTURE_IMAGE_SIZE_UXGA}, {"1920x1080", CAPTURE_IMAGE_SIZE_1080P}, {"1920x1200", CAPTURE_IMAGE_SIZE_WUXGA}, {"1872x1408", CAPTURE_IMAGE_SIZE_2_5M}, {"2048x1536", CAPTURE_IMAGE_SIZE_3M}, {"3744x1408", CAPTURE_IMAGE_SIZE_5M}, {"960x1080", CAPTURE_IMAGE_SIZE_1080N}, {"2592x1520", CAPTURE_IMAGE_SIZE_4M}, {"3072x2048", CAPTURE_IMAGE_SIZE_6M}, {"3264x2448", CAPTURE_IMAGE_SIZE_8M}, {"4000x3000", CAPTURE_IMAGE_SIZE_12M}, {"4096x2160", CAPTURE_IMAGE_SIZE_4K}, // 电影级4K {"3840x2160", CAPTURE_IMAGE_SIZE_4K}, // UHD 4K {"640x720", CAPTURE_IMAGE_SIZE_720N}, {"1024x576", CAPTURE_IMAGE_SIZE_WSVGA}, {"640x360", CAPTURE_IMAGE_SIZE_NHD}, {"1024x1536", CAPTURE_IMAGE_SIZE_3M_N}, {"1296x1520", CAPTURE_IMAGE_SIZE_4M_N}, {"1872x1408", CAPTURE_IMAGE_SIZE_5M_N}, {"2048x2160", CAPTURE_IMAGE_SIZE_4K_N}, // 通用 {"1920x2160", CAPTURE_IMAGE_SIZE_4K_N} // 海思方案 }; // 查找匹配项 auto it = resolutionMap.find(normalized); if (it != resolutionMap.end()) { return it->second; } throw std::invalid_argument("Unsupported resolution: " + resolutionStr); } ``` #### 设计要点说明 1. **输入规范化处理** - 移除所有空格:`"1280 x 720"` → `"1280x720"` - 统一小写格式:`"1280X720"` → `"1280x720"` - 支持多种分隔符:`x`/`X`/`*`/`×` 统一转为 `x` 2. **多格式兼容设计** - 支持 PAL/NTSC 双格式:`704x576` 和 `704x480` 均映射到 `CAPTURE_IMAGE_SIZE_D1` - 支持 4K 多标准:`4096x2160`(电影)和 `3840x2160`(UHD)均映射到 `CAPTURE_IMAGE_SIZE_4K` 3. **特殊案例处理** - 高冲突分辨率:`1872x1408` 同时映射到: ```cpp {"1872x1408", CAPTURE_IMAGE_SIZE_2_5M}, // 标准2.5M {"1872x1408", CAPTURE_IMAGE_SIZE_5M_N} // 特殊5M_N模式 ``` 实际使用中需根据上下文选择(默认优先返回首次匹配值) 4. **错误处理机制** - 抛出 `std::invalid_argument` 异常处理未知分辨率 - 包含原始字符串的错误信息便于调试 #### 使用示例 ```cpp // 将分辨率字符串转换为枚举值 std::string input = "1920x1080"; try { CaptureImageSize size = stringToCaptureImageSize(input); std::cout << "Converted to enum: " << static_cast<int>(size) << std::endl; // 输出: Converted to enum: 14 (CAPTURE_IMAGE_SIZE_1080P) } catch (const std::invalid_argument& e) { std::cerr << "Error: " << e.what() << std::endl; } // 处理特殊分辨率 std::string specialRes = "1872x1408"; CaptureImageSize size = stringToCaptureImageSize(specialRes); // 返回 CAPTURE_IMAGE_SIZE_2_5M 或 CAPTURE_IMAGE_SIZE_5M_N ``` ### 视频采集参数配置建议 在视频采集系统中,分辨率选择常与采集参数配合使用[^1]: ```cpp // 设置理想分辨率(浏览器优先尝试匹配) void setIdealResolution(CaptureImageSize size) { int width = 0, height = 0; // ... 获取分辨率对应的宽高值 // 配置媒体约束 mediaConstraints.video = { { "width", { ideal: width } }, { "height", { ideal: height } } }; } ``` 当需要精确匹配分辨率时: ```cpp // 设置精确分辨率(强制匹配) void setExactResolution(CaptureImageSize size) { int width = 0, height = 0; // ... 获取分辨率对应的宽高值 mediaConstraints.video = { { "width", { exact: width } }, { "height", { exact: height } } }; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值