突破編程_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 <iostream>  
#include <unordered_map>  
#include <string>  class Solution
{
public:bool isContainsAllCharacters(const std::string& mainString, const std::string& subString) {// 初始化哈希表  std::unordered_map<char, int> 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<char, int>創建了一個名為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 << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;mainString = "mississippi";subString = "missip";std::cout << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;mainString = "abcdefg";subString = "defghijklmnop";std::cout << "Does \"" << mainString << "\" contain all characters of \"" << subString << "\"? "<< (solution.isContainsAllCharacters(mainString, subString) ? "Yes" : "No") << std::endl;return 0;
}

上面代碼的輸出為:

Does "abcdefghijklmnopqrstuvwxyz" contain all characters of "abcde"? Yes
Does "mississippi" contain all characters of "missip"? Yes
Does "abcdefg" contain all characters of "defghijklmnop"? No

3.2 使用排序和比較的方法

這種方法的思路是,如果主字符串包含子字符串的所有字符,那么對兩個字符串進行排序后,排序后的子字符串應該是排序后的主字符串的一個子序列。該方法的優點是它不需要使用額外的數據結構來記錄字符的出現次數,而是通過比較排序后的字符串來直接得出結論。然而,它的缺點是需要對字符串進行排序,這可能會增加一些計算復雜度。
如下為算法實現代碼:

#include <iostream>  
#include <cctype>  
#include <string>  
#include <algorithm> // 用于std::sortclass Solution 
{
public:bool isContainsAllCharacters(const std::string& mainString, const std::string& subString) {// 對兩個字符串進行排序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 < sorted_sub.length() && j < sorted_main.length()) {if (sorted_sub[i] == sorted_main[j]) {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
解釋: 子字符串是主字符串的前綴,因此主字符串必然包含子字符串中的所有字符。

這些測試用例涵蓋了不同的場景,從基礎情況到邊緣情況,有助于驗證代碼的正確性和健壯性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719523.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719523.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719523.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

代碼隨想錄算法訓練營第31天—貪心算法05 | ● 435. 無重疊區間 ● *763.劃分字母區間 ● *56. 合并區間

435. 無重疊區間 https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html 考點 貪心算法重疊區間 我的思路 先按照區間左坐標進行排序&#xff0c;方便后續處理進行for循環&#xff0c;循環范圍是0到倒數第二個元素如果當前區間和下一區間重疊…

在Linux以命令行方式(靜默方式/非圖形化方式)安裝MATLAB(正版)

1.根據教程&#xff0c;下載windows版本matlab&#xff0c;打開圖形化界面&#xff0c;選擇linux版本的只下載不安裝 2.獲取安裝文件夾 3.獲取許可證 4.安裝 &#xff08;1&#xff09;跳過引用文章的2.2章節 &#xff08;2&#xff09;本文的安裝文件夾代替引用文章的解壓IS…

Java進階(鎖)——鎖的升級,synchronized與lock鎖區別

目錄 引出Java中鎖升級synchronized與lock鎖區別 緩存三兄弟&#xff1a;緩存擊穿、穿透、雪崩緩存擊穿緩存穿透緩存雪崩 總結 引出 Java進階&#xff08;鎖&#xff09;——鎖的升級&#xff0c;synchronized與lock鎖區別 Java中鎖升級 看一段代碼&#xff1a; public class…

Fastwhisper + Pyannote 實現 ASR + 說話者識別

文章目錄 前言一、faster-whisper簡單介紹二、pyannote.audio介紹三、faster-whisper pyannote.audio 實現語者識別四、多說幾句 前言 最近在研究ASR相關的業務&#xff0c;也是調研了不少模型&#xff0c;踩了不少坑&#xff0c;ASR這塊&#xff0c;目前中文普通話效果最好的…

Scrapy與分布式開發(1.1):課程導學

Scrapy與分布式開發&#xff1a;從入門到精通&#xff0c;打造高效爬蟲系統 課程大綱 在這個專欄中&#xff0c;我們將一起探索Scrapy框架的魅力&#xff0c;以及如何通過Scrapy-Redis實現分布式爬蟲的開發。在本課程導學中&#xff0c;我們將為您簡要介紹課程的學習目標、內容…

Verilog Coding Styles For Improved Simulation Efficiency論文學習記錄

原文基于Verilog-XL仿真器&#xff0c;測試了以下幾種方式對仿真效率的影響。 1. 使用 Case 語句而不是 if / else if 語句 八選一多路選擇器 case 實現效率比 if / else if 提升 6% 。 2. 如果可以盡量不使用 begin end 語句 使用 begin end 的 ff 觸發器比不使用 begin end …

初學者學習51還是STM32

初學者學習51還是STM32 在嵌入式系統領域&#xff0c;51和STM32是兩種常見的單片機架構。對于初學者來說&#xff0c;選擇學習哪種架構可能會成為一個難題。本文將對初學者學習51和STM32進行比較&#xff0c;以幫助讀者做出明智的選擇。 1. 51架構 51架構是指Intel 8051系列…

深度相機xyz點云文件三維坐標和jpg圖像文件二維坐標的相互變換函數

深度相機同時拍攝xyz點云文件和jpg圖像文件。xyz文件里面包含三維坐標[x,y,z]和jpg圖像文件包含二維坐標[x&#xff0c;y],但是不能直接進行變換&#xff0c;需要一定的步驟來推演。 下面函數是通過box二維框[xmin, ymin, xmax, ymax, _, _ ]去截取xyz文件中對應box里面的點云…

MyCAT學習——在openEuler22.03中安裝MyCAT2(網盤下載版)

準備工作 因為MyCAT 2基于JDK 1.8開發。也需要在虛擬機中安裝JDK&#xff08;JDK官網就能下載&#xff0c;我這提供一個捷徑&#xff09; jdk-8u401-linux-x64.rpmhttps://pan.baidu.com/s/1ywcDsxYOmfZONpmH9oDjfw?pwdrhel下載對應的tar安裝包,以及對應的jar包 安裝程序包…

九州金榜|孩子厭學要怎么辦?

孩子從小學到初中再到高中&#xff0c;孩子出現厭學情緒很正常&#xff0c;但是孩子出現厭學情緒后&#xff0c;就必然會影響到孩子學習成績&#xff0c;孩子產生厭學情緒的原因有哪些呢&#xff1f;只有找準孩子厭學原因才能去幫助孩子怎樣去克服孩子厭學情緒&#xff0c;下面…

ajax請求servlet成功但接收不到返回數據問題

ajax請求servlet成功但接收不到返回數據問題 javaweb初學者&#xff0c;最近老師布置的課設&#xff0c;所有功能都完成了&#xff0c;唯獨ajax與servlet交互出現問題&#xff0c;無論怎么調試都收不到數據 查詢兩天無果&#xff0c;剛才無意間看到 Crabime前輩的文章才恍然大…

深入解析YOLO:實時目標檢測技術的革命者

深入解析YOLO&#xff1a;實時目標檢測技術的革命者 目標檢測作為計算機視覺領域的一個核心任務&#xff0c;一直以來都是研究的熱點。而YOLO&#xff08;You Only Look Once&#xff09;技術作為其中的杰出代表&#xff0c;以其獨特的處理方式和卓越的性能&#xff0c;成為了…

day34貪心算法 part03

1005. K 次取反后最大化的數組和 簡單 給你一個整數數組 nums 和一個整數 k &#xff0c;按以下方法修改該數組&#xff1a; 選擇某個下標 i 并將 nums[i] 替換為 -nums[i] 。 重復這個過程恰好 k 次。可以多次選擇同一個下標 i 。 以這種方式修改數組后&#xff0c;返回數…

力扣棧隊列篇

以下思路來自代碼隨想錄以及官方題解。 文章目錄 232.用棧實現隊列225.用隊列實現棧20.有效的括號1047.刪除字符串中所有相鄰重復項150.逆波蘭表達式求值347.前K個高頻元素 232.用棧實現隊列 請你僅使用兩個棧實現先入先出隊列。隊列應當支持一般隊列支持的所有操作&#xff…

OSError: [WinError 1455] 頁面文件太小,無法完成操作。

[問題描述]&#xff1a;OSError: [WinError 1455] 頁面文件太小&#xff0c;無法完成操作。 原因1&#xff1a;線程數太大 方法&#xff1a;改小線程&#xff08;workers&#xff09;數。 原因2&#xff1a;虛擬內存太小或為0&#xff0c;調大虛擬內存。 方法&#xff1a;右鍵…

mysql索引過長Specialed key was too long的解決方法

在創建要給表的時候遇到一個有意思的問題&#xff0c;提示Specified key was too long; max key length is 767 bytes&#xff0c;從描述上來看&#xff0c;是Key太長&#xff0c;超過了指定的 767字節限制。通常出現在嘗試創建一個過長的唯一鍵&#xff08;UNIQUE KEY&#xf…

Vue.js 實用技巧:深入理解 Vue.mixin

&#x1f90d; 前端開發工程師、技術日更博主、已過CET6 &#x1f368; 阿珊和她的貓_CSDN博客專家、23年度博客之星前端領域TOP1 &#x1f560; 牛客高級專題作者、打造專欄《前端面試必備》 、《2024面試高頻手撕題》 &#x1f35a; 藍橋云課簽約作者、上架課程《Vue.js 和 E…

uniapp真機運行的時候顯示同步資源失敗,未得到同步資源的授權,請停止運行后重新運行,并注意手機上的授權提示

1、問題 在添加清單文件之前&#xff0c;項目運行都是好好的&#xff0c;添加了清單項目以后&#xff0c;基座一打就報這個錯&#xff0c;并且手機在安裝基座的時候會提示解析包時失敗&#xff0c; 2、解決方案 打開我的清單文件&#xff0c;我發現我和官網寫的清單文件不一…

華為OD機試“HJ2計算某字符出現次數”不區分大小寫Java編程解答

描述 寫出一個程序&#xff0c;接受一個由字母、數字和空格組成的字符串&#xff0c;和一個字符&#xff0c;然后輸出輸入字符串中該字符的出現次數。&#xff08;不區分大小寫字母&#xff09; 數據范圍&#xff1a; 1≤n≤1000 輸入描述&#xff1a; 第一行輸入一個由字…

【Linux進程間通信】共享內存

【Linux進程間通信】共享內存 目錄 【Linux進程間通信】共享內存system V共享內存共享內存示意圖共享內存的數據結構共享內存函數將共享內存掛接到對應的進程將共享內存取消掛接釋放共享內存 共享內存的特性共享內存擴展共享內存配合管道進行使用 作者&#xff1a;愛寫代碼的剛…