突破编程 |
您所在的位置:网站首页 › c语言判断字符串是否包含某个字符串 › 突破编程 |
1 算法题 :判断一个字符串是否包含另一个字符串的所有字符(不一定连续)
1.1 题目含义
判断一个字符串(称为“主字符串”或“大字符串”)是否包含另一个字符串(称为“子字符串”或“小字符串”)的所有字符,且不论这些字符在主字符串中的顺序和连续性。换句话说,我们要确认子字符串的每一个字符至少在主字符串中出现一次。 1.2 示例示例 1: 输入: 主字符串: “abcdefghijklmnopqrstuvwxyz”子字符串: “abcde”输出: true 解释: 主字符串包含子字符串的所有字符。 示例 2: 输入: 主字符串: “mississippi”子字符串: “missip”输出: true 解释: 尽管 “missip” 在主字符串中不是连续的,但主字符串包含子字符串的所有字符。 示例 3: 输入: 主字符串: “abcdefg”子字符串: “defghijklmnop”输出: false 解释: 主字符串不包含子字符串的所有字符,因为 “hijklmnop” 中的字符在主字符串中没有出现。 2 解题思路解题思路如下: (1)初始化哈希表: 在 C++ 中,我们可以使用std::unordered_map来作为哈希表。首先,遍历子字符串,对于每个字符,我们在unordered_map中增加其计数。 (2)遍历主字符串并更新哈希表: 然后,遍历主字符串。对于主字符串中的每个字符,我们检查它是否在unordered_map中。如果在,则将其对应的计数减一。如果不在,说明主字符串中缺少该字符,因此可以立即返回false。 (3)检查哈希表: 在遍历完主字符串后,我们检查 unordered_map 中所有字符的计数是否都已经归零。如果所有计数都为零,说明主字符串包含了子字符串的所有字符,返回 true;如果存在任何非零计数,说明主字符串缺少某些字符,返回 false。 (4)返回结果: 根据unordered_map的状态,返回相应的布尔值。 3 算法实现代码 3.1 使用哈希表如下为算法实现代码: #include #include #include class Solution { public: bool isContainsAllCharacters(const std::string& mainString, const std::string& subString) { // 初始化哈希表 std::unordered_map charCounts; for (char c : subString) { charCounts[c]++; } // 遍历主字符串并更新哈希表 for (char c : mainString) { if (charCounts.find(c) != charCounts.end()) { charCounts[c]--; if (charCounts[c] == 0) { // 如果字符的计数减到0,从哈希表中删除该字符 charCounts.erase(c); } } } // 检查哈希表 return charCounts.empty(); // 如果哈希表为空,说明所有字符都被找到了 } };在 isContainsAllCharacters 成员函数中,首先使用std::unordered_map创建了一个名为charCounts的哈希表。这个哈希表将存储 subString中 每个字符及其出现的次数(遍历 subString 中的每个字符 c,并在 charCounts 中增加该字符的计数。如果字符 c 在 charCounts 中不存在,它会被插入到哈希表中并设置计数为 1;如果它已经存在,则计数增加 1)。 接下来,使用 find 方法来检查字符 c 是否存在于 charCounts 中。如果字符 c 在 charCounts 中存在,将其计数减 1。如果减1后计数变为 0,说明 mainString 中的这个字符与 subString 中的字符数量相匹配,可以从 charCounts中 删除这个字符。 最后,如果哈希表为空,说明 mainString 包含了 subString 中的所有字符,因为所有在 subString 中出现的字符都已经在 mainString 中被匹配并从哈希表中删除了。如果哈希表不为空,则意味着至少有一个 subString 中的字符在 mainString 中没有出现。 调用上面的算法,并得到输出: int main() { Solution solution; std::string mainString = "abcdefghijklmnopqrstuvwxyz"; std::string subString = "abcde"; std::cout // 对两个字符串进行排序 std::string sorted_main = mainString; std::string sorted_sub = subString; std::sort(sorted_main.begin(), sorted_main.end()); std::sort(sorted_sub.begin(), sorted_sub.end()); // 使用双指针法检查 sorted_sub 是否是 sorted_main 的子序列 int i = 0, j = 0; while (i i++; // 移动到 sorted_sub 的下一个字符 } j++; // 移动到 sorted_main 的下一个字符 } // 如果 sorted_sub 的所有字符都在 sorted_main 中找到,则 sorted_sub 是 sorted_main 的子序列 return sorted_sub.length() == i; } };在这个实现中,首先使用 std::sort 函数对这两个字符串进行排序。排序后,sorted_main 和 sorted_sub 分别包含与 mainString 和 subString 相同但已排序的字符。 然后,使用双指针法检查 sorted_sub 是否是 sorted_main 的子序列(注意:无论是否找到匹配的字符,都将 j 增加 1,以继续检查 sorted_main 的下一个字符)。 接着,判断 sorted_sub 的所有字符是否都在 sorted_main 中找到(如果 sorted_sub 的所有字符都在 sorted_main 中找到,那么 i 的值应该等于 sorted_sub 的长度)。 4 测试用例以下是针对上面算法的测试用例: (1)基础测试用例: 输入: 主字符串: “abcdefg”子字符串: “bcd”输出: true 解释: 主字符串包含子字符串的所有字符。 (2)包含所有字符但顺序不同: 输入: 主字符串: “bacdefg”子字符串: “abc”输出: true 解释: 虽然字符顺序不同,但主字符串包含子字符串的所有字符符。 (3)缺少一个字符: 输入: 主字符串: “abdefg”子字符串: “abc”输出: false 解释: 主字符串缺少子字符串中的一个字符 ‘c’。 (4)包含重复字符: 输入: 主字符串: “aabbbccc”子字符串: “abc”输出: true 解释: 即使主字符串中的字符有重复,但它仍然包含子字符串中的所有字符。 (5)子字符串是主字符串的前缀: 输入: 主字符串: “abcdefg”子字符串: “abc”输出: true 解释: 子字符串是主字符串的前缀,因此主字符串必然包含子字符串中的所有字符。 这些测试用例涵盖了不同的场景,从基础情况到边缘情况,有助于验证代码的正确性和健壮性。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |