قم بكتابة دالة function تستقبل قيمة نصية من نوع string. تقوم بالدالة ببناء وإرجاع قيمة نصية بناءًا على القيمة المدخلة. عن طريق تكرار الاحرف بعدد معين تحدده القيمة المدخلة. على سبيل المثال:
4a
يعني أنه يجب تكرار الحرف
“a”
أربع مرات.
النتيجة المتوقعة هي aaaa.
تقوم الدالة بإنشاء النص المطلوب باتباع تلك التعليمات، باستخدام مبدأ
Last-In, FirstOut
المخرجات المتوقعة
الاختبار 1
المدخلات (Inputs)
expression = ‘3[a]2[bc]’
المخرجات (Outputs)
‘aaabcbc’
الاختبار 2
المدخلات (Inputs)
expression = ‘3[a2[c]]’
المخرجات (Outputs)
‘accaccacc’
الاختبار 3
المدخلات (Inputs)
expression = ‘2[abc]3[cd]ef’
المخرجات (Outputs)
‘abcabccdcdcdef’
الاختبار 4
المدخلات (Inputs)
expression = ‘abc3[cd]xyz’
المخرجات (Outputs)
‘abccdcdcdxyz’
الحل :
ملحوظه : كلمة المكدس (Stack) في الحل معناها : “آخر عنصر يدخل هو أول عنصر يخرج”
اضعط لرؤية الحل
(def repeat_chars(instruction:
stack = []
result = ''
for char in instruction:
if char.isdigit():
# إذا كان الحرف رقماً، أضفه إلى المكدس
stack.append(int(char))
else:
# إذا كان الحرف حرفاً، أخرجه من المكدس وكرر الحرف
if stack:
repeat_count = stack.pop()
result += char * repeat_count
return result
حل اخر
(def string_builder(expression:
stack = []
for char in expression:
if char != ']':
stack.append(char) # إضافة الحرف إلى المكدس
else:
# فك النص داخل الأقواس
substring = ''
while stack and stack[-1] != '[':
substring = stack.pop() + substring
stack.pop() # إزالة '['
# الحصول على العدد السابق للنص
num = ''
while stack and stack[-1].isdigit():
num = stack.pop() + num
stack.append(int(num) * substring) # إضافة النص المكرر إلى المكدس
return ''.join(stack)
عندك نص فيه أرقام وحروف، وكل رقم بين قوسين [] معناه إن الحروف اللي جواه تتكرر بنفس العدد.
يعني لو عندك: 3[a] → معناها نكرر a ثلاث مرات → “aaa” 2[bc] → نكرر “bc” مرتين → “bcbc” 3[a2[c]] → هنا دخلنا في توسيع الفكرة شوي، معناها:
2[c] → تكرر “c” مرتين → “cc”
3[cc] → نكرر “cc” ثلاث مرات → “cc” + “cc” + “cc” = “accaccacc”
كيف نحلها؟
هنستخدم حاجة اسمها المكدس (Stack)، ودي ببساطة صندوق بنحط فيه الحاجات وآخر حاجة دخلت هي أول حاجة تطلع.
زي لما تحط كتب فوق بعض، الكتاب اللي فوق هو اللي بتشيله أول حاجة.
الحل خطوة بخطوة:
هنمر على كل حرف في النص المدخل، ونتعامل معاه كالتالي:
لو لقينا رقم:
بنخزنه علشان نعرف قد إيه هنكرر النص اللي بعده.
لو لقينا [ (فتح قوس):
معناها إننا لازم نخزن النص اللي قبل كده والرقم اللي قريناه ونعمل إعادة ضبط للمتغيرات.
لو لقينا ] (قفل قوس):
بنطلع آخر نص دخلناه مع الرقم ونكرر النص اللي بين الأقواس بالعدد المطلوب.
لو لقينا حرف عادي:
بنضيفه على طول للنص الحالي.
الكود مع تبسيط الشرح جوّاه:
def decode_string(s):
stack = [] # المكدس اللي هنستخدمه لتخزين النصوص المؤقتة
current_string = "" # النص الحالي اللي بنبنيه
current_num = 0 # الرقم الحالي اللي بنشوفه
for char in s:
if char.isdigit():
# لو الحرف رقم، بنخزنه (عشان لو كان رقم من أكتر من خانة زي 12 بدل 1 و2)
current_num = current_num * 10 + int(char)
elif char == "[":
# لو لقينا [، معناها بداية جزء جديد، نحفظ اللي قبلها ونبدأ جديد
stack.append((current_string, current_num))
current_string = "" # نبدأ نص جديد
current_num = 0 # نرجع الرقم للصفر
elif char == "]":
# لو لقينا ]، معناها لازم نطلع آخر حاجة من المكدس ونعيد بنائها
last_string, num = stack.pop()
current_string = last_string + current_string * num
else:
# لو حرف عادي، نضيفه للنص الحالي
current_string += char
return current_string
# اختبارات عشان نشوف الكود شغال كويس
print(decode_string('3[a]2[bc]')) # هتطبع: 'aaabcbc'
print(decode_string('3[a2[c]]')) # هتطبع: 'accaccacc'
print(decode_string('2[abc]3[cd]ef')) # هتطبع: 'abcabccdcdcdef'
print(decode_string('abc3[cd]xyz')) # هتطبع: 'abccdcdcdxyz'
ليه استخدمنا المكدس؟
لأن عندنا أجزاء متداخلة، وكل جزء لازم يتفك بطريقة عكسية، وده بالضبط اللي يعمله المكدس.
مثال توضيحي للي بيحصل في الكود مع 3[a2[c]]:
3[a2[c]]
نلاقي 2[c] → نكرر “c” مرتين → “cc”
نحطها مكانها → 3[a[cc]]
3[a[cc]] → نكرر “acc” ثلاث مرات → “accaccacc”
كده الفكرة بسيطة وسهلة؟
لو في جزء مش واضح قولي وأنا أشرحه بأبسط شكل ممكن ان شاء الله
!