JavaScript での文字列操作の領域を探索すると、特定の文字列を回文に変換できるかどうかを判断するという興味深い課題が明らかになります。回文、つまり表と裏が同じように読める単語やフレーズは本質的に魅力的であり、その神秘的な特性を解明しようとする開発者の好奇心を刺激します。この記事では、JavaScript の本質的に強力な言語機能とアルゴリズムを使用して、文字列を回文に変換できるかどうかをチェックする複雑さを解明するための啓発的な旅をしていきます。文字列操作を深く掘り下げ、革新的な技術を採用することで、文字列を回文に変換する奇跡の謎を解き明かし、それによって目の肥えた JavaScript 実践者としてのスキルを向上させます。
問題文
当面の課題は、1 文字だけを削除することで特定の文字列を回文に変換できるかどうかを効率的に判断できる JavaScript アルゴリズムを開発することです。回文は、前方または後方に読んでも変化しません。このアルゴリズムでは、回文を作成するために必要に応じて個々の文字を削除するオプションを考慮しながら、入力文字列を徹底的に分析し、その個々の文字を検査する必要があります。出力は、文字列を回文に変換できるかどうかを示すブール値になります。よりよく理解するために、次の例を考えてみましょう。
入力例
"racecar"
サンプル出力
true
最大 1 文字を削除することで文字列を回文に実際に変換できることを示します。
方法
この記事では、JavaScript で上記の問題を解決するための複数の異なる方法を見ていきます-
-
ダブルポインタ
-
再帰
-
動的プログラミング
方法 1: 2 つのポインター
JavaScript で文字列が回文であるかどうかを確認するという一般的な問題は、2 つのポインター メソッドを使用して解決できます。これには、2 つのポインター (1 つは文字列の先頭に、もう 1 つは文字列の末尾に) を初期化し、それらのポインターにある文字を比較し、それらを中央に向かって移動することが含まれます。これを行うには、文字列を入力として受け取り、ポインターを初期化し、変数を変更する JavaScript 関数を定義します。次に、while ループを使用して文字を比較し、一致しない修飾子をインクリメントし、それに応じてポインタを移動します。ループが終了したら、変更が 1 以下であるかどうかを確認し、回文を形成できるかどうかを判断します。最後に、文字列から回文を作成できるかどうかを示すブール値を返します。
例
canBePalindrome 関数は、最大 1 文字を削除することで文字列を回文にできるかどうかをチェックします。2 ポインター メソッドを使用して文字列を反復処理し、文字を比較します。文字が等しい場合、両方のポインタが中心に向かって移動します。そうでない場合は、隣接する文字を比較して、文字を削除できるかどうかを確認します。文字が削除された場合は false を返します。false を返さずにループが完了した場合は true を返し、文字列が回文である可能性があることを示します。下部の使用例は機能を示しています。
function canBePalindrome(str) {
let left = 0;
let right = str.length - 1;
let removed = false;
while (left < right) {
if (str[left] !== str[right]) {
if (removed) {
return false; // Already removed a character, can't remove more
}
// Try removing either the character at the left or right pointer
if (str[left + 1] === str[right]) {
left++;
} else if (str[left] === str[right - 1]) {
right--;
} else {
return false; // Unable to make the string a palindrome by removing one character
}
removed = true;
}
left++;
right--;
}
return true; // The string can be made a palindrome by removing at most one character
}
// Example usage:
console.log(canBePalindrome("racecar")); // true
console.log(canBePalindrome("abccdba")); // true
console.log(canBePalindrome("abccba")); // true
console.log(canBePalindrome("abcdcba")); // true
console.log(canBePalindrome("abcddba")); // false
console.log(canBePalindrome("abcdefg")); // false
出力
以下はコンソール出力です-
true
true
true
true
true
false
方法 2: 再帰
JavaScript で再帰を使用して文字列を回文にできるかどうかを確認するには、入力文字列を受け取る canBePalindrome() という関数を定義します。基本ケースでは、文字列の長さが 1 以下の場合に true を返します。それ以外の場合は、最初と最後の文字を比較し、更新された文字列で canBePalindrome() を再帰的に呼び出し、それらが等しい場合はそれらの文字を削除します。このプロセスは、基本ケースに到達するまで繰り返されます。最初と最後の文字が等しくない場合は false を返します。最後に、入力文字列を使用して canBePalindrome() が呼び出され、結果が保存され、さらに処理が続行されるか、結果に応じて適切なメッセージが表示されます。
例
このコードでは、canFormPalindrome 関数は文字列を入力として受け取り、最大 1 文字を削除して文字列を回文にできる場合は true を返し、それ以外の場合は false を返します。isPalindrome 関数は、部分文字列が回文であるかどうかをチェックするヘルパー関数です。
function canFormPalindrome(str) {
// Helper function to check if a substring is a palindrome
function isPalindrome(left, right) {
while (left < right) {
if (str[left] !== str[right]) {
return false;
}
left++;
right--;
}
return true;
}
// Recursive function to check if the string can be made a palindrome
function checkPalindrome(left, right) {
if (left >= right) {
return true; // Base case: single character or empty string
}
if (str[left] === str[right]) {
return checkPalindrome(left + 1, right - 1); // Characters match, check inner substring
}
// Try removing either left or right character and check the remaining substring
return isPalindrome(left + 1, right) || isPalindrome(left, right - 1);
}
// Call the recursive function starting from the endpoints of the string
return checkPalindrome(0, str.length - 1);
}
// Example usage
console.log(canFormPalindrome("abcba")); // true
console.log(canFormPalindrome("abbca")); // true
console.log(canFormPalindrome("abcd")); // false
出力
以下はコンソール出力です-
true
true
false
方法 3: 動的プログラミング
JavaScript で動的プログラミングを使用して文字列を回文に変換できるかどうかを確認するには、文字列を入力として受け取る canBePalindrome という関数を定義します。部分問題の結果を保存する動的プログラミング テーブルを作成します。2 つのポインターを使用して文字列を両端から繰り返し、それらの位置の文字を比較します。それらが同じ場合は、それに応じてポインタを移動します。異なる場合は、ポインター間の部分文字列がテーブル内ですでに処理されているかどうかを確認します。そうでない場合は、部分文字列に対して canBePalindrome 関数を再帰的に呼び出し、結果を保存します。左右のポインターから文字を除外することを検討し、どちらの場合も true を返す場合はテーブルを更新します。テーブルを更新した後、文字列全体を表すエントリに格納されている値を返し、回文に再配置できるかどうかを判断します。このアプローチでは、動的プログラミングを利用し、問題をサブ問題に分解することで、問題を効率的に解決します。
例
このコードでは、canFormPalindrome 関数は文字列 str を入力として受け取り、最大 1 文字を削除することで文字列を回文にできるかどうかを示すブール値を返します。この関数は、動的プログラミング テーブル dp を使用して中間結果を保存し、str の考えられるすべての部分文字列をチェックします。最後に、文字列全体が回文になる場合は true を返し、そうでない場合は false を返します。
function canFormPalindrome(str) {
const n = str.length;
// Create a 2D dynamic programming table
const dp = Array(n)
.fill(false)
.map(() => Array(n).fill(false));
// Initialize the diagonal to true
for (let i = 0; i < n; i++) {
dp[i][i] = true;
}
// Fill the table diagonally
for (let len = 2; len <= n; len++) {
for (let i = 0; i < n - len + 1; i++) {
const j = i + len - 1;
if (str[i] === str[j]) {
// Characters at the current indices are equal
dp[i][j] = dp[i + 1][j - 1];
} else {
// Try removing either the character at index i or j
dp[i][j] = dp[i + 1][j] || dp[i][j - 1];
}
}
}
// Return true if the whole string can be made a palindrome by removing at most one character
return dp[0][n - 1];
}
// Example usage:
const str = "abca";
const canBePalindrome = canFormPalindrome(str);
console.log(canBePalindrome);
出力
以下はコンソール出力です-
true
結論は
要約すると、JavaScript を使用して文字列を回文に変換できるかどうかを判断するプロセスは多面的な作業です。さまざまな文字列操作手法を利用し、体系的なアプローチを採用することで、回文対称性の実現可能性を効率的に判断できます。文字の頻度を注意深く評価し、珍しい文字列に対するアルゴリズムを活用することで、興味深い洞察と創造的なソリューションが得られる可能性があります。このような知的探求に取り組むことで、プログラマーは言語操作の複雑さを掘り下げることができ、その結果、言語領域の満足のいく探求が実現します。結局のところ、文字列内の回文の可能性を認識できるということは、プログラミング言語としての JavaScript の創意工夫と多用途性の証拠となります。