在各種解決問(wèn)題的場(chǎng)景中操作字符串至關(guān)重要。發(fā)現(xiàn)給定字符串的排列可以優(yōu)化大于相鄰字符的字符數(shù),這是一個(gè)有趣的難題,需要重新排列字符串的字符以生成盡可能多的相鄰字符對(duì),其中左側(cè)字符小于右側(cè)字符。 p>
方法
有多種方法可以解決字符串的排列,其中最大字符數(shù)大于與其直接相鄰的字符數(shù)。
方法 1 ? 回溯法與剪枝 ?
方法 2 – 動(dòng)態(tài)規(guī)劃 –
方法3 – 堆算法-
方法 4 – 帶修剪的詞典順序 –
方法一:回溯法與剪枝
使用回溯算法生成字符串的所有排列。
在每一步中,檢查當(dāng)前排列是否有比其相鄰字符更多的字符大于迄今為止找到的最大值。
如果沒(méi)有,請(qǐng)盡早修剪分支并回溯以避免不必要的計(jì)算。
語(yǔ)法
function backtrack_permutation(string): n = length(string) max_count = [0]
登錄后復(fù)制
存儲(chǔ)大于相鄰字符的最大字符數(shù)
result = [None] * n
登錄后復(fù)制
存儲(chǔ)最終排列
function backtrack(curr_permutation, used_chars): nonlocal max_count if length(cu permutation) == n:
登錄后復(fù)制
計(jì)算大于相鄰字符的字符數(shù)量
count = 0 for i in range(1, n - 1): if cu permutation [i - 1] < cu permutation[i] > cu permutation [i + 1]: count += 1 if count > max count [0]: max count [0] = count result [:] = cu permutation
登錄后復(fù)制
更新結(jié)果
return for i in range(n): if not used_chars[i]:
登錄后復(fù)制
選擇下一個(gè)字符
used_chars[i] = true curr_permutation.append(string[i])
登錄后復(fù)制
回溯到下一個(gè)位置
backtrack(curr_permutation, used_chars)
登錄后復(fù)制
撤銷選擇
used_chars[i] = false curr_permutation.pop()
登錄后復(fù)制
開(kāi)始回溯過(guò)程
used_chars = [false] * n
登錄后復(fù)制
跟蹤已使用的字符
curr_permutation = [] backtrack(curr_permutation, used_chars) return result.
登錄后復(fù)制
算法
步驟 1 – 用一個(gè)空字符串開(kāi)始 max_permutation。
應(yīng)定義輔助函數(shù)回溯(current_permutation、remaining_characters)。
步驟2 – 如果字符串remaining_characters為空 –
如果當(dāng)前排列的長(zhǎng)度比最大排列的長(zhǎng)度長(zhǎng),將max_permutation設(shè)置為current_permutation。
返回。
步驟 3 – 在迭代中,遍歷剩余字符中的每個(gè)字符 c –
將 c 添加到 current_permutation 中以創(chuàng)建 new_permutation。
如果new_permutation的長(zhǎng)度大于1且其最后一個(gè)字符不再長(zhǎng)于其前面的字符,則跳過(guò)此迭代。
從remaining_characters中取出c,生成新的new_remaining。
迭代調(diào)用回溯(new_permutation、new_remaining)。
第四步 – 調(diào)用回溯函數(shù),將輸入文本作為remaining_characters,將空字符串作為current_permutation。
第 5 步 – 提供輸出 max_permutation。
示例 1
此程序通過(guò)首先將輸入字符串“abcd”按升序排列來(lái)操作。隨后,使用回溯函數(shù)生成每個(gè)可能的排列,該函數(shù)僅考慮大于前一個(gè)字符的字符,從而避免了不符合條件的重復(fù)排列。此外,isValidPermutation函數(shù)根據(jù)每個(gè)字符與其前一個(gè)字符進(jìn)行評(píng)估,對(duì)于任何等于或小于后者的情況返回false。
結(jié)果是,這個(gè)有目的的過(guò)程會(huì)創(chuàng)建所有有效的排列,其中每個(gè)字符的最大數(shù)量都高于其相鄰字符。我們可以自由地進(jìn)一步定制給定的輸入字符串、代碼和邏輯,以滿足個(gè)人的要求。
#include <iostream> #include <string> #include <algorithm> using namespace std; int maxCount = 0; bool isValidPermutation(const string& str) { for (int i = 1; i < str.length(); i++) { if (str[i] <= str[i - 1]) { return false; } } return true; } void backtrack(string& str, int pos) { if (pos == str.length()) { if (isValidPermutation(str)) { cout << str << endl; } return; } for (int i = pos; i < str.length(); i++) { swap(str[pos], str[i]); if (str[pos] > str[pos - 1]) { backtrack(str, pos + 1); } swap(str[pos], str[i]); } } int main() { string input = "abcd"; sort(input.begin(), input.end()); // Sort the input string initially backtrack(input, 1); return 0; }
登錄后復(fù)制
輸出
abcd
登錄后復(fù)制
方法二:動(dòng)態(tài)規(guī)劃
使用動(dòng)態(tài)規(guī)劃逐步生成字符串的排列。
從空前綴開(kāi)始,考慮所有可能的位置,迭代地向其中添加字符。
維護(hù)當(dāng)前前綴中大于其相鄰字符的字符數(shù)。
修剪計(jì)數(shù)已經(jīng)低于目前發(fā)現(xiàn)的最大值的分支。
語(yǔ)法
def find_max_permutation(string): n = len(string) dp = [0] * n dp[0] = 1
登錄后復(fù)制
動(dòng)態(tài)編程循環(huán)
for i in range (1, n):
登錄后復(fù)制
檢查當(dāng)前字符是否大于其相鄰字符
if string[i] > string[i-1]:
登錄后復(fù)制
如果是,則將計(jì)數(shù)增加1
dp[i] = dp[i-1] + 1 else:
登錄后復(fù)制
如果不是,計(jì)數(shù)是相同的
dp[i] = dp[i-1]
登錄后復(fù)制
查找 dp 數(shù)組中的最大計(jì)數(shù)
max_count = max(dp) return max_count
登錄后復(fù)制
算法
步驟 1 – 創(chuàng)建一個(gè)名為 maxPerm(str) 的函數(shù),接受字符串作為輸入,并返回滿足指定條件的最長(zhǎng)字符串的排列。
步驟 2 – 首先初始化長(zhǎng)度為 n 的數(shù)組(稱為 dp),其中 n 等于輸入字符串 str 的長(zhǎng)度。以位置 i 結(jié)束的最大排列串存儲(chǔ)在每個(gè)元素 dp[i] 中。
第三步 – 將 dp [0] 初始化為字符串 str 的第一個(gè)字符。
第四步 – 從索引1到n-1迭代遍歷str的字符 –
初始化一個(gè)空字符串curr來(lái)存儲(chǔ)當(dāng)前最大排列字符串。
對(duì)于索引 i 處的每個(gè)字符,將其與索引 i-1 處的前一個(gè)字符進(jìn)行比較。
如果 str[i] 大于 str[i-1],將 str[i] 添加到 curr 中。
否則,將 str[i-1] 追加到 curr 中。
使用 dp[i-1] 和 curr 之間的最大值更新 dp[i]。
第5步 – 循環(huán)完成后,最大排列字符串將存儲(chǔ)在dp[n-1]中。
第 6 步 – 返回 dp[n-1] 作為結(jié)果。
Example 2
的中文翻譯為:
示例2
在此示例中,輸入字符串被硬編碼為“abcbdb”。 findMaxPermutation 函數(shù)使用動(dòng)態(tài)編程來(lái)計(jì)算每個(gè)索引處大于其相鄰字符的最大字符數(shù)。然后,它通過(guò)回溯表來(lái)重建具有最大計(jì)數(shù)的字符串。生成的最大排列在 main 函數(shù)中打印。
#include <iostream> #include <string> #include <vector> std::string findMaxPermutation(const std::string& str) { int n = str.length(); // make a table to store the maximum count of characters // larger than their adjacent characters std::vector<std::vector<int>> dp(n, std::vector<int>(2, 0)); // Initialize the table for the base case dp[0][0] = 0; // Count when str[0] is not included dp[0][1] = 1; // Count when str[0] is included // Calculate the maximum count for each index for (int i = 1; i < n; i++) { // When str[i] is not involved, the count is the maximum // when str[i-1] is included or not dp[i][0] = std::max(dp[i-1][0], dp[i-1][1]); // When str[i] is involved, the count is the count when // str[i-1] is not included plus 1 dp[i][1] = dp[i-1][0] + 1; } // The more count will be the largest of the last two values int maxCount = std::max(dp[n-1][0], dp[n-1][1]); // Reconstruct the string with the maximum count std::string maxPerm; int i = n - 1; int count = maxCount; // Start from the end and check which character to include while (i >= 0) { if ((dp[i][0] == count - 1 && dp[i][1] == count) || (dp[i][0] == count && dp[i][1] == count)) { maxPerm = str[i] + maxPerm; count--; } i--; } return maxPerm; } int main() { std::string str = "abcbdb"; std::string maxPerm = findMaxPermutation(str); std::cout << "String: " << str << std::endl; std::cout << "Max Permutation: " << maxPerm << std::endl; return 0; }
登錄后復(fù)制
輸出
String: abcbdb Max Permutation: bbb
登錄后復(fù)制
方法三:堆算法
實(shí)現(xiàn)Heap算法,高效地生成字符串的所有排列。
生成每個(gè)排列后,計(jì)算大于其相鄰字符的字符數(shù)量。
保持追蹤到目前為止找到的最大計(jì)數(shù),并根據(jù)需要進(jìn)行更新。
語(yǔ)法
function generatePermutations(string): n = length(string) characters = array of n elements initialized with string's characters generatePermutationsHelper(n, characters) function generatePermutationsHelper(n, characters): if n = 1: checkAndPrintPermutation(characters) else: for i = 0 to n-1: generatePermutationsHelper(n-1, characters) if n is even: swap characters[i] and characters[n-1] else: swap characters [0] and characters[n-1]
登錄后復(fù)制
算法
第一步 – 已經(jīng)初始化了一個(gè)數(shù)組,用于存儲(chǔ)輸入字符串的字符。
第 2 步 – 繼續(xù)創(chuàng)建一個(gè)函數(shù),并將其命名為“generatePermutations”,帶有兩個(gè)參數(shù) – 一個(gè)最終變量“size”,用于確定數(shù)組的大小,以及一個(gè)名為“arr”的數(shù)組,其中包含字符串字符。
步驟 3 – 如果大小為 1,則通過(guò)將數(shù)組中的字符組合在一起,直到最大字符數(shù)超過(guò)連續(xù)字符數(shù),打印當(dāng)前排列。
步驟 4 – 如果不是,則函數(shù)返回。為了從索引 0 到 ‘size – 1’ 迭代數(shù)組,我們使用一個(gè)名為 ‘i’ 的變量。
第 5 步 – 在此迭代中,我們進(jìn)一步迭代參數(shù)大小 – 1 和錯(cuò)誤的generatePermutations 函數(shù)。
第 6 步 – 如果 size 恰好是奇數(shù),則我們將數(shù)組中索引 0 處的元素替換為索引“size – 1”處的元素。
第 7 步 – 類似地,如果 size 結(jié)果是偶數(shù),我們將數(shù)組中索引“i”處的元素替換為索引“size – 1”。
步驟8 – 最后,我們使用初始數(shù)組大小和數(shù)組本身作為參數(shù)調(diào)用”generatePermutations”函數(shù)。
示例 1
以下的C++示例使用Heap’s算法創(chuàng)建字符串的排列,并識(shí)別出在其相鄰字符上具有最大字符數(shù)的排列 ?
為了說(shuō)明問(wèn)題,在這個(gè)例子中使用”abcd”作為輸入字符串。可以修改變量來(lái)使用不同的輸入字符串。如果排列滿足具有比其鄰居更多字符的要求,則找到isValidPermutation函數(shù)是否有效。generatePermutations函數(shù)使用堆棧方法來(lái)跟蹤具有最多字符的排列,以便它可以生成輸入字符串的每個(gè)可能的排列。主函數(shù)將最大數(shù)量和排列本身作為輸出打印。
#include <iostream> #include <algorithm> using namespace std; // Function to check if the permutation satisfies the condition bool isValidPermutation(const string& perm) { int n = perm.length(); for (int i = 0; i < n - 1; i++) { if (abs(perm[i] - perm[i + 1]) <= 1) return false; } return true; } // Function to swap two characters in a string void swapChar(char& a, char& b) { char temp = a; a = b; b = temp; } // Heap's Algorithm for generating permutations void generatePermutations(string& str, int n, int& maxCount, string& maxPerm, int idx = 0) { if (idx == n - 1) { if (isValidPermutation(str)) { int count = count_if(str.begin(), str.end(), [](char c) { return isalpha(c) && c >= 'A' && c <= 'Z'; }); if (count > maxCount) { maxCount = count; maxPerm = str; } } return; } for (int i = idx; i < n; i++) { swapChar(str[idx], str[i]); generatePermutations(str, n, maxCount, maxPerm, idx + 1); swapChar(str[idx], str[i]); } } int main() { string str = "abcd"; int n = str.length(); int maxCount = 0; string maxPerm; generatePermutations(str, n, maxCount, maxPerm); if (maxCount == 0) { cout << "No valid permutation found." << endl; } else { cout << "Maximum number of characters greater than adjacent characters: " << maxCount << endl; cout << "Permutation with the maximum count: " << maxPerm << endl; } return 0; }
登錄后復(fù)制
輸出
No valid permutation found.
登錄后復(fù)制
方法4:字典序排序與剪枝
按字典順序?qū)ψ址淖址M(jìn)行排序。
生成排序字符串的排列。
在每一步中,檢查當(dāng)前排列是否滿足最大字符數(shù)大于其相鄰字符的條件。
如果不是這樣,請(qǐng)?zhí)^(guò)具有相似前綴的剩余排列,以避免不必要的計(jì)算。
語(yǔ)法
生成字符串所有排列的函數(shù)
function generatePermutations(string):
登錄后復(fù)制
TODO:排列生成的實(shí)現(xiàn)
檢查字符是否大于其相鄰字符的函數(shù)
function isGreaterAdjacent(char1, char2):
登錄后復(fù)制
TODO:比較邏輯的實(shí)現(xiàn)
找到具有大于相鄰字符的最大數(shù)量的排列的函數(shù)
function findMaxAdjacentPermutation(string):
登錄后復(fù)制
生成字符串的所有排列
permutations = generatePermutations(string)
登錄后復(fù)制
初始化變量
max_permutation = "" max_count = 0
登錄后復(fù)制
遍歷每個(gè)排列
for permutation in permutations: count = 0
登錄后復(fù)制
迭代排列中的每個(gè)字符(不包括最后一個(gè)字符)
for i from 0 to length(permutation) - 2: char1 = permutation[i] char2 = permutation[i + 1]
登錄后復(fù)制
檢查當(dāng)前字符是否大于其相鄰字符
if isGreaterAdjacent(char1, char2): count = count + 1
登錄后復(fù)制
檢查當(dāng)前排列的計(jì)數(shù)是否大于先前的最大值
if count > max_count: max_permutation = permutation max_count = count
登錄后復(fù)制
返回具有最大計(jì)數(shù)的排列
return max_permutation
登錄后復(fù)制
算法
第一步 – 從輸入字符串開(kāi)始。
第 2 步 – 按字典順序?qū)ψ址M(jìn)行排序以獲得初始排列。
第 3 步 – 將變量 maxCount 初始化為 0,以跟蹤大于相鄰字符的最大字符數(shù)。
第 4 步 – 初始化變量 maxPermutation 以存儲(chǔ)最大計(jì)數(shù)的排列。
第 5 步 – 當(dāng)有下一個(gè)排列時(shí) –
將變量 count 初始化為 0,以跟蹤當(dāng)前大于相鄰字符的字符數(shù)。
對(duì)于當(dāng)前排列中的每個(gè)字符 –
檢查當(dāng)前字符是否大于其前一個(gè)字符和后一個(gè)字符(如果存在)。
如果滿足條件,則將計(jì)數(shù)增加 1。
如果計(jì)數(shù)大于最大計(jì)數(shù)(maxCount)-
將maxCount更新為當(dāng)前計(jì)數(shù)。
將 maxPermutation 更新為當(dāng)前排列。
步驟 6 – 將 maxPermutation 作為結(jié)果返回。
示例 1
對(duì)于此示例,為簡(jiǎn)單起見(jiàn),讓我們考慮固定字符串“abcde”。
在這個(gè)例子中,countAdjacentGreater函數(shù)統(tǒng)計(jì)字符串中相鄰字符大于其前一個(gè)字符的數(shù)量。findMaxPermutation函數(shù)生成輸入字符串的所有排列,并檢查每個(gè)排列,找出具有最大數(shù)量相鄰字符大于的那個(gè)。
主要函數(shù)初始化輸入字符串”abcde”和跟蹤最大計(jì)數(shù)和最大排列的變量。它調(diào)用findMaxPermutation函數(shù)來(lái)找到最大排列。
#include <iostream> #include <algorithm> #include <string> using namespace std; int countAdjacentGreater(const string& str) { int count = 0; for (int i = 0; i < str.length() - 1; i++) { if (str[i] < str[i + 1]) { count++; } } return count; } void findMaxPermutation(string& str, int& maxCount, string& maxPerm) { sort(str.begin(), str.end()); do { int count = countAdjacentGreater(str); if (count > maxCount) { maxCount = count; maxPerm = str; } } while (next_permutation(str.begin(), str.end())); } int main() { string str = "abcde"; int maxCount = 0; string maxPerm; findMaxPermutation(str, maxCount, maxPerm); cout << "String with the maximum number of characters greater than its adjacent characters: " << maxPerm << endl; cout << "Count of adjacent characters greater in the maximum permutation: " << maxCount << endl; return 0; }
登錄后復(fù)制
輸出
String with the maximum number of characters greater than its adjacent characters: abcde Count of adjacent characters greater in the maximum permutation: 4
登錄后復(fù)制
結(jié)論
總之,找到最大字符數(shù)大于相鄰字符的字符串的排列問(wèn)題是字符串操作中的一個(gè)有趣的挑戰(zhàn)。通過(guò)分析給定的字符串并有策略地重新排列其字符,可以實(shí)現(xiàn)所需的排列。這個(gè)問(wèn)題凸顯了在使用字符串和排列時(shí)仔細(xì)檢查和創(chuàng)造性思維的重要性。
以上就是字符串的排列,使得其中字符的數(shù)量大于其相鄰字符的數(shù)量的最大化的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注www.xfxf.net其它相關(guān)文章!