logo

مشكلة فواصل الكلمات باستخدام التراجع

نظرا لتسلسل غير فارغ  ق  وقاموس  إملاء[]  تحتوي على قائمة بالكلمات غير الفارغة المطلوب إرجاعها  كل ما هو ممكن طرق لكسر الجملة  فردي  كلمات القاموس.
ملحوظة:  يمكن إعادة استخدام نفس الكلمة في القاموس  عديد  مرات أثناء الكسر.
أمثلة:  

مدخل: s = catsanddog  dict = [قطط قطط وكلب رمل]
الإخراج:  
القطط والكلب 
كلب الرمال القط
توضيح: يتم تقسيم السلسلة إلى طريقتين أعلاه، وكل طريقة هي كلمات قاموس صالحة.

مدخل: s = الأناناس  dict = [قلم التفاح، قلم التفاح، الصنوبر، الأناناس]
الإخراج:  
تفاح صنوبر قلم تفاح 
أناناس قلم تفاح 
تفاح صنوبر 
توضيح: يتم تقسيم السلسلة إلى 3 طرق أعلاه، وكلها كلمات قاموس صالحة.

يقترب:



للنهج العودي هناك حالتين في كل خطوة (حجم السلسلة يتناقص في كل خطوة):

  • يشمل السلسلة الفرعية الحالية في الحل إذا كانت السلسلة الفرعية موجودة في القاموس بشكل متكرر تحقق من بقية السلسلة بدءًا من الفهرس التالي.
  • يتخطى ال السلسلة الفرعية الحالية والانتقال إلى السلسلة الفرعية المحتملة التالية بدءًا من نفس الفهرس.

wordBreak(sstart) = wordBreak(s end) إذا كان القاموس[start:end] ∈

الحالة الأساسية: wordBreak(s start) = true يشير هذا إلى أنه تم إنشاء جملة صالحة لسلسلة الإدخال المحددة.

خطوات تنفيذ الفكرة السابقة:

  • تحويل قاموس في مجموعة التجزئة للبحث السريع.
  • إذا مؤشر البداية يصل إلى طول من السلسلة (السلاسل) فهذا يعني أ جملة صالحة تم تشييده. يضيف الجملة الحالية (curr) إلى النتيجة.
  • حلقة من خلال كل سلسلة فرعية ابتداء من يبدأ و إنهاء في جميع المواقف الممكنة (النهاية).
  • لكل سلسلة فرعية تحقق مما إذا كان موجود في القاموس (ديكتسيت).
  • إذا كانت صالحة :
    • إلحاق الكلمة إلى الجملة الحالية (curr).
    • استدعاء بشكل متكرر وظيفة ل الجزء المتبقي من السلسلة (من النهاية فصاعدا).
  • بعد إرجاع المكالمة العودية يعيد حالة curr للتأكد من أن فرع الاستكشاف التالي يبدأ بـ الجملة الصحيحة.
C++
// C++ implementation to find valid word // break using Recursion #include    using namespace std; // Helper function to perform backtracking void wordBreakHelper(string& s unordered_set<string>& dictSet   string& curr vector<string>& res   int start) {  // If start reaches the end of the string  // save the result  if (start == s.length()) {  res.push_back(curr);  return;  }  // Try every possible substring from the current index  for (int end = start + 1; end <= s.length(); ++end) {  string word = s.substr(start end - start);  // Check if the word exists in the dictionary  if (dictSet.count(word)) {  string prev = curr;  // Append the word to the current sentence  if (!curr.empty()) {  curr += ' ';  }  curr += word;  // Recurse for the remaining string  wordBreakHelper(s dictSet curr res end);  // Backtrack to restore the current sentence  curr = prev;  }  } } // Main function to generate all possible sentence breaks vector<string> wordBreak(string s vector<string>& dict) {    // Convert dictionary vector  // to an unordered set  unordered_set<string>  dictSet(dict.begin() dict.end());  vector<string> res;   string curr;   wordBreakHelper(s dictSet curr res 0);  return res;  } int main() {    string s = 'ilikesamsungmobile';  vector<string> dict = {'i' 'like' 'sam' 'sung'  'samsung' 'mobile' 'ice'  'and' 'cream' 'icecream'  'man' 'go' 'mango'};  vector<string> result = wordBreak(s dict);  for (string sentence : result) {  cout << sentence << endl;  }  return 0; } 
Java
// Java implementation to find valid  // word break using Recursion import java.util.*; class GfG {  // Helper function to perform backtracking  static void wordBreakHelper(String s HashSet<String> dictSet   String curr List<String> res   int start) {  // If start reaches the end of the string  // save the result  if (start == s.length()) {  res.add(curr);  return;  }  // Try every possible substring from the current index  for (int end = start + 1; end <= s.length(); ++end) {  String word = s.substring(start end);  // Check if the word exists in the dictionary  if (dictSet.contains(word)) {  String prev = curr;  // Append the word to the current sentence  if (!curr.isEmpty()) {  curr += ' ';  }  curr += word;  // Recurse for the remaining string  wordBreakHelper(s dictSet curr res end);  // Backtrack to restore the current sentence  curr = prev;  }  }  }  // Main function to generate all possible sentence breaks  static List<String> wordBreak(String s List<String> dict) {  // Convert dictionary vector to a HashSet  HashSet<String> dictSet = new HashSet<>(dict);  List<String> res = new ArrayList<>();  String curr = '';  wordBreakHelper(s dictSet curr res 0);  return res;  }  public static void main(String[] args) {  String s = 'ilikesamsungmobile';  List<String> dict = Arrays.asList('i' 'like' 'sam' 'sung'  'samsung' 'mobile' 'ice'  'and' 'cream' 'icecream'  'man' 'go' 'mango');  List<String> result = wordBreak(s dict);  for (String sentence : result) {  System.out.println(sentence);  }  } } 
Python
# Python implementation to find valid  # word break using Recursion def wordBreakHelper(s dictSet curr res start): # If start reaches the end of the string # save the result if start == len(s): res.append(curr) return # Try every possible substring from the current index for end in range(start + 1 len(s) + 1): word = s[start:end] # Check if the word exists in the dictionary if word in dictSet: prev = curr # Append the word to the current sentence if curr: curr += ' ' curr += word # Recurse for the remaining string wordBreakHelper(s dictSet curr res end) # Backtrack to restore the current sentence curr = prev def wordBreak(s dict): # Convert dictionary list to a set dictSet = set(dict) res = [] curr = '' wordBreakHelper(s dictSet curr res 0) return res if __name__=='__main__': s = 'ilikesamsungmobile' dict = ['i' 'like' 'sam' 'sung' 'samsung' 'mobile' 'ice' 'and' 'cream' 'icecream' 'man' 'go' 'mango'] result = wordBreak(s dict) for sentence in result: print(sentence) 
C#
// C# implementation to find valid word  // break using Recursion using System; using System.Collections.Generic; class GfG {    // Helper function to perform backtracking  static void wordBreakHelper(string s HashSet<string> dictSet  ref string curr ref List<string> res  int start) {    // If start reaches the end of the string  // save the result  if (start == s.Length) {  res.Add(curr);  return;  }  // Try every possible substring from the current index  for (int end = start + 1; end <= s.Length; ++end) {    string word = s.Substring(start end - start);  // Check if the word exists in the dictionary  if (dictSet.Contains(word)) {  string prev = curr;  // Append the word to the current sentence  if (curr.Length > 0) {  curr += ' ';  }  curr += word;  // Recurse for the remaining string  wordBreakHelper(s dictSet ref curr   ref res end);  // Backtrack to restore the current sentence  curr = prev;  }  }  }  // Main function to generate all possible sentence breaks  static List<string> wordBreak(string s   List<string> dict) {    // Convert dictionary list to a HashSet  HashSet<string> dictSet   = new HashSet<string>(dict);  List<string> res = new List<string>();  string curr = '';  wordBreakHelper(s dictSet ref curr ref res 0);  return res;  }  static void Main() {    string s = 'ilikesamsungmobile';  List<string> dict  = new List<string> {'i' 'like' 'sam' 'sung'  'samsung' 'mobile' 'ice'  'and' 'cream' 'icecream'  'man' 'go' 'mango'};  List<string> result = wordBreak(s dict);  foreach (string sentence in result) {  Console.WriteLine(sentence);  }  } } 
JavaScript
// JavaScript implementation to find valid  // word break using Recursion // Helper function to perform backtracking function wordBreakHelper(s dictSet curr res start) {  // If start reaches the end of the string save the result  if (start === s.length) {  res.push(curr);  return;  }  // Try every possible substring from the current index  for (let end = start + 1; end <= s.length; ++end) {  let word = s.substring(start end);  // Check if the word exists in the dictionary  if (dictSet.has(word)) {  let prev = curr;  // Append the word to the current sentence  if (curr.length > 0) {  curr += ' ';  }  curr += word;  // Recurse for the remaining string  wordBreakHelper(s dictSet curr res end);  // Backtrack to restore the current sentence  curr = prev;  }  } } // Main function to generate all possible sentence breaks function wordBreak(s dict) {  // Convert dictionary array to a Set  let dictSet = new Set(dict);  let res = [];  let curr = '';  wordBreakHelper(s dictSet curr res 0);  return res; } let s = 'ilikesamsungmobile'; let dict = ['i' 'like' 'sam' 'sung'  'samsung' 'mobile' 'ice'  'and' 'cream' 'icecream'  'man' 'go' 'mango']; let result = wordBreak(s dict); result.forEach((sentence) => {  console.log(sentence);  }); 

الإخراج
i like sam sung mobile i like samsung mobile 

تعقيد الوقت: O((2^n) * k) بالنسبة لسلسلة بطول n، هناك 2^n من الأقسام المحتملة وكل فحص لسلسلة فرعية يستغرق O(k) وقتًا (متوسط ​​طول السلسلة الفرعية k) مما يؤدي إلى O((2^n) * k).
المساحة المساعدة: O(n) بسبب مكدس العودية يمكن أن يصل إلى عمق O(n) في أسوأ الحالات.

إنشاء اختبار