C++程式用於尋找給定字串是否有長度為2或更長的重複子序列
給定一個字串,找出一個長度至少為兩個、在字串中重複的子序列。子序列元素編號的索引不能處於相同的順序。
string s = "PNDPNSP"; print("Repeated subsequence of length 2 or more: ", (check(s) ? "Yes" : "No"));
讓我們來看看下面的幾個例子,以了解這種方法在不同情況下的工作原理 -
範例 1 - str = "PNDPNSP"
#Explanation − 這裡,答案是true,因為字串中有一個重複出現的子序列"PN"。
範例 2 - str = "PPND"
解釋 - 這裡,答案是錯誤的,因為字串中沒有重複的長度至少為兩個的子序列。
範例3 − str = "PPNP"
解釋 - 這裡,答案是正確的,因為「PP」索引0和1以及「PP」索引1和3存在,並且使用的「PP」在子序列中按順序具有不同的索引。 (基於 0 的索引)
Brute force Approach
的中文翻譯為:暴力破解方法
這種方法將產生長度為 2(最小長度)的所有可能的子序列,並尋找我們是否已經看到該子序列與已找到的子序列。如果子序列已經存在,我們傳回 true 並終止程式;否則,在完成迭代後,如果我們什麼也沒找到,則傳回 false。
在最壞的情況下,這個子序列可能不存在,我們最終會產生所有可能的結果。
兩個長度的子序列並將它們儲存起來。因此,假設您對計算的子序列進行哈希處理以實現O(1)的插入和搜索,這將變為O(n^2)。總的子序列也是O(n^2),所以儲存空間也是如此。修改後的最長公共子序列(LCS)
LCS 演算法找到 2 個字串中最長的公共子序列。它是一種標準的動態規劃方法,使用二維矩陣的迭代方法。時間複雜度為O(n^2)。我們將僅在修改後的方法中搜尋給定字串本身。儘管如此,我們還將檢查當前位置的索引是否不相同。
範例
查看下面的 C 程式碼來實現修改後的最長公共子序列演算法,該演算法有助於我們的方法找到長度為 2 或以上的重複子序列 -
#include <iostream> using namespace std; bool modifiedLongestCommonSubsequence(string s) { int n = s.length(); int dp[n+1][n+1]; for (int i=0; i<=n; i++) fill(dp[i], dp[i]+n+1, 0); for (int i=1; i<=n; i++) { for (int j=1; j<=n; j++) { if (s[i-1]==s[j-1] && i!=j) { dp[i][j] = 1 + dp[i-1][j-1]; } else { dp[i][j] = max(dp[i][j-1], dp[i-1][j]); } } } if(dp[n][n] > 1) return true; return false; } int main() { string str = "PNDPNSP"; cout << "Repeated subsequence of length 2 or more: " << (modifiedLongestCommonSubsequence(str) ? "Yes" : "No"); return 0; }
輸出
Repeated subsequence of length 2 or more: Yes
當然,時間和空間複雜度是O(n^2),但是從第一種方法來看,它更加優雅且容易產生O(1)的哈希。
改進的解決方案
在這個方法中,我們將嘗試在先前的方法基礎上進行一些觀察。
觀察1 − 如果一個字元出現超過兩次,答案總是真的。讓我們看看為什麼?
範例 - 在字串 str = "AVHJFBABVNHFA" 中,我們在位置 0、6 和 12 中有 "AAA"。所以 我們可以將索引為0和6的"AA"作為一個子序列,以及將索引為6和12的"AA"作為一個子序列 作為另一個。
觀察 2 - 如果一個字元只重複一次,它不能對我們的結果做出貢獻 子序列,因為它只會在最多一個子序列中可用。它將無法運作 因為我們需要至少兩個子序列。所以我們可以刪除或忽略所有字符 發生在同一時間。
觀察3 − 如果一個字串是回文,並且前兩個觀察都適用,那麼答案是 除非字串長度為奇數,否則始終為 false。讓我們看看為什麼?
範例 - 字串 str = "PNDDNP"
解釋 - 現在,字元不按順序排列,因此我們永遠無法找到 子序列具有相同的順序,因此不可能。
範例
根據上述所有三個觀察結果,我們得出的結論是,如果我們刪除字串中出現一次的所有字符,然後檢查某個字符是否出現兩次以上或者字符串是否不是回文,那麼我們的答案是正確的。讓我們看看改進後的解決方案在 C 中的實作 -
#include <iostream> using namespace std; bool isPalindrome(string s) { for(int i=0;i<s.size()/2;i++) { if(s[i]!=s[s.size()-1-i]) { return false; } } return true; } bool check(string s) { int hash[26] = {0}; for (int i = 0; i < s.size(); i++) { hash[s[i]-'a']++; if (hash[s[i]-'a'] > 2) { return true; } } int k = 0; string mstr = ""; for (int i = 0; i < s.size(); i++) { if (hash[s[i]-'a'] > 1) { mstr[k++] = s[i]; } } if (isPalindrome(mstr)) { return false; } return true; } int main() { string s = "PNDPNSP"; cout << "Repeated subsequence of length 2 or more: " << (check(s) ? "Yes" : "No"); return 0; }
輸出
Repeated subsequence of length 2 or more: Yes
結論
我們得出結論,使用觀察和哈希是解決這個問題的最佳方法。時間複雜度為O(n)。空間複雜度也是O(n)的順序,創建一個新的字串和常數26個字元的雜湊。
以上是C++程式用於尋找給定字串是否有長度為2或更長的重複子序列的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

關閉iPhone版「查找」後會發生什麼事? 「尋找我的iPhone」可協助您定位遺失或被竊的裝置。啟用後,「尋找我的iPhone」可讓您在地圖上追蹤裝置的位置、播放聲音並協助您找回裝置。 「查找」還包括一個啟動鎖,可防止任何人使用您的iPhone。當您關閉「尋找我的iPhone」時,您將失去所有這些功能,這可能會使恢復遺失的Apple裝置變得困難。雖然「尋找我的iPhone」非常有用,但當您想出售、捐贈、以舊換新手機或想要將其送去更換電池或任何其他服務時,您應該停用它。這樣做將確保沒有人可以訪問有關您

Apple的「尋找」應用程式可讓您定位您的iPhone或其他設備,以防止遺失或遺忘。雖然「查找」是一個有用的工具來追蹤設備,但如果您關注隱私問題、不想耗盡電池或其他原因,您可能想要停用它。幸運的是,有幾種方法可以關閉iPhone上的“查找”,我們將在這篇文章中解釋所有這些方法。如何在iPhone上關閉「尋找」[4種方法]您可以透過四種方式關閉iPhone的「查找」。如果您使用方法1關閉“查找”,則可以從要停用它的裝置上執行此操作。若要繼續執行方法2、3和4,要關閉「尋找」的iPhone應關閉電源或

使用C#中的Array.IndexOf函數來找出陣列中某個元素的索引在C#程式中,當我們需要尋找陣列中某個元素的索引時,可以使用Array.IndexOf函數。 Array.IndexOf函數會在指定的陣列範圍內尋找指定的元素,並傳回其第一次出現的索引。如果未找到該元素,則傳回-1。下面是一段範例程式碼,示範如何使用Array.IndexOf函數來找出陣列中某個元

硬碟序號和MAC位址是電腦硬體中重要的標識符,它們在管理和維護電腦系統時非常有用。本文將介紹如何尋找硬碟序號和MAC位址。一、尋找硬碟序號硬碟序號是硬碟製造商為了辨識和追蹤硬碟的唯一識別碼。在不同的作業系統中,尋找硬碟序號的方法略有不同。 Windows系統:開啟命令提示字元(在開始功能表中搜尋「cmd」),然後輸入以下命令並按下回車鍵:wmicdisk

PHP中的glob()函數用來尋找檔案或目錄,是一種強大的檔案操作函數。它可以根據指定的模式匹配,返回檔案或目錄的路徑。 glob()函數的語法如下:glob(pattern,flags)其中,pattern表示要匹配的模式字串,可以是一個通配符表達式,如*.txt(匹配以.txt結尾的文件),或者是具體的文件路徑。 flags是一個可選參數,用來控制函數

雙曲函數是使用雙曲線而不是圓定義的,與普通三角函數相當。它從提供的弧度角傳回雙曲正弦函數中的比率參數。但要做相反的事,或者換句話說。如果我們想要根據雙曲正弦值計算角度,我們需要像雙曲反正弦運算一樣的反雙曲三角運算。本課程將示範如何使用C++中的雙曲反正弦(asinh)函數,並使用雙曲正弦值(以弧度為單位)計算角度。雙曲反正弦運算遵循下列公式-$$\mathrm{sinh^{-1}x\:=\:In(x\:+\:\sqrt{x^2\:+\:1})},其中\:In\:是\:自然對數\:(log_e\:k)

映射是C++中的一種特殊類型的容器,其中每個元素都是一對兩個值,即鍵值和映射值。鍵值用於索引每個項目,映射值是與鍵關聯的值。無論映射值是否唯一,鍵始終是唯一的。要在C++中列印映射元素,我們必須使用迭代器。一組項目中的一個元素由迭代器物件指示。迭代器主要與陣列和其他類型的容器(例如向量)一起使用,並且它們具有一組特定的操作,可用於識別特定範圍內的特定元素。可以增加或減少迭代器來引用範圍或容器中存在的不同元素。迭代器指向範圍內特定元素的記憶體位置。使用迭代器在C++中列印地圖首先,我們先來看看如何定義

rename函數將檔案或目錄從舊名稱變更為新名稱。此操作類似於移動操作。因此,我們也可以使用此rename函數來移動檔案。此函數存在於stdio.h庫頭檔中。 rename函數的語法如下:intrename(constchar*oldname,constchar*newname);rename()函數的函數它接受兩個參數。一個是oldname,一個是newname。這兩個參數都是指向常數字元的指針,用於定義檔案的舊名稱和新名稱。如果檔案重新命名成功,則傳回零;否則,傳回非零整數。在重新命名操作期間
