الفرق بين المراجعتين لصفحة: «Algorithms/infix to prefix»

من موسوعة حسوب
أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE:تحويل التعبير المرتّب وسطيًا إلى تعبير مرتّب قبليًا}}</noinclude> '''التعبير المرتّب...'
 
لا ملخص تعديل
 
سطر 8: سطر 8:


# قلب التعبير المرتّب وسطيًا، أي يتحوّل التعبير <code>A+B*C</code> إلى <code>C*B+A</code>. ويجب الانتباه إلى أنّ عملية القلب تشمل الأقواس، بمعنى أنّ كل <code>')'</code> يتحول إلى <code>'('</code>، وكلّ <code>'('</code> يتحوّل إلى <code>')'</code>.
# قلب التعبير المرتّب وسطيًا، أي يتحوّل التعبير <code>A+B*C</code> إلى <code>C*B+A</code>. ويجب الانتباه إلى أنّ عملية القلب تشمل الأقواس، بمعنى أنّ كل <code>')'</code> يتحول إلى <code>'('</code>، وكلّ <code>'('</code> يتحوّل إلى <code>')'</code>.
# الحصول على التعبير المرتّب بعديًا.
# [[Algorithms/infix to postfix|الحصول على التعبير المرتّب بعديًا]].
# قلب التعبير المرتّب بعديًا للحصول على تعبير مرتّبٍ قبليًا.
# قلب التعبير المرتّب بعديًا للحصول على تعبير مرتّبٍ قبليًا.


سطر 126: سطر 126:
== التعقيد الزمني ==
== التعقيد الزمني ==


تنفّذ العمليات الخاصة بالمكادس مثل <code>push()‎</code> و <code>pop()‎</code> في تعقيد زمني خطي، ولمّا كانت الخوارزمية تجري مسحًا على جميع الحروف في التعبير المعطى مرة واحدة فإنّ التعقيد الزمني لهذه الخوارزمية خطّي ويبلغ المقدار <code>O(n)‎</code>.
تنفّذ العمليات الخاصة [[Algorithms/stacks|بالمكادس]] مثل <code>push()‎</code> و <code>pop()‎</code> في تعقيد زمني خطي، ولمّا كانت الخوارزمية تجري مسحًا على جميع الحروف في التعبير المعطى مرة واحدة فإنّ التعقيد الزمني لهذه الخوارزمية خطّي ويبلغ المقدار <code>O(n)‎</code>.


== مصادر ==
== مصادر ==

المراجعة الحالية بتاريخ 08:14، 22 ديسمبر 2019

التعبير المرتّب وسطيًا Infix: هو تعبير رياضي يتوسّط فيه العامل المعاملين الذين يعمل عليهما.
التعبير المرتّب قبليًّا Prefix: هو تعبير رياضي يسبق فيه العامل المعاملين الذين يعمل عليهما.

خطوات الخوارزمية

تتبع هذه الخوارزمية الخطوات التالية:

  1. قلب التعبير المرتّب وسطيًا، أي يتحوّل التعبير A+B*C إلى C*B+A. ويجب الانتباه إلى أنّ عملية القلب تشمل الأقواس، بمعنى أنّ كل ')' يتحول إلى '('، وكلّ '(' يتحوّل إلى ')'.
  2. الحصول على التعبير المرتّب بعديًا.
  3. قلب التعبير المرتّب بعديًا للحصول على تعبير مرتّبٍ قبليًا.

تنفيذ الخوارزمية

تعرض الأمثلة التالية طريقة تنفيذ الخوارزمية في عدد من لغات البرمجة:

#include <bits/stdc++.h> 
using namespace std; 

bool isOperator(char c) 
{ 
	return (!isalpha(c) && !isdigit(c)); 
} 

int getPriority(char C) 
{ 
	if (C == '-' || C == '+') 
		return 1; 
	else if (C == '*' || C == '/') 
		return 2; 
	else if (C == '^') 
		return 3; 
	return 0; 
} 

string infixToPostfix(string infix) 
{ 
	infix = '(' + infix + ')'; 
	int l = infix.size(); 
	stack<char> char_stack; 
	string output; 

	for (int i = 0; i < l; i++) { 

		// إن كان الحرف الممسوح عاملًا، يُضاف إلى سلسلة المخرجات النصية 
		if (isalpha(infix[i]) || isdigit(infix[i])) 
			output += infix[i]; 

		// إن كان الحرف الممسوح هو القوس ')' فإنّه يضاف إلى المكدس 
		else if (infix[i] == '(') 
			char_stack.push('('); 

		// إن كان الحرف الممسوح هو القوس '(' يُحذف هو وجميع العناصر التي تليه 
		//  وينقل إلى سلسلة المخرجات النصية وصولًا إلى القوس ')' في المكدس 
		else if (infix[i] == ')') { 

			while (char_stack.top() != '(') { 
				output += char_stack.top(); 
				char_stack.pop(); 
			} 

			// حذف القوس ')' من المكدس
			char_stack.pop(); 
		} 

		// إن جرى مسح العامل 
		else { 
			
			if (isOperator(char_stack.top())) { 
				while (getPriority(infix[i]) 
				<= getPriority(char_stack.top())) { 
					output += char_stack.top(); 
					char_stack.pop(); 
				} 

				// إضافة العامل الحالي إلى المكدس
				char_stack.push(infix[i]); 
			} 
		} 
	} 
	return output; 
} 

string infixToPrefix(string infix) 
{ 
	/* قلب السلسلة النصية
	استبدال الأقواس
	الحصول على التعبير المرتب بعديًا ثم قلبه */
	int l = infix.size(); 

	// قلب التعبير المرتب وسطيًا
	reverse(infix.begin(), infix.end()); 

	// تبديل الأقواس
	for (int i = 0; i < l; i++) { 

		if (infix[i] == '(') { 
			infix[i] = ')'; 
			i++; 
		} 
		else if (infix[i] == ')') { 
			infix[i] = '('; 
			i++; 
		} 
	} 

	string prefix = infixToPostfix(infix); 

	// قلب التعبير المرتب بعديًا
	reverse(prefix.begin(), prefix.end()); 

	return prefix; 
} 

// اختبار الدالة السابقة
int main() 
{ 
	string s = ("(a-b/c)*(a/k-l)"); 
	cout << infixToPrefix(s) << std::endl; 
	return 0; 
}

تعطي الشيفرة السابقة المخرجات التالية:

*-a/bc-/akl

التعقيد الزمني

تنفّذ العمليات الخاصة بالمكادس مثل push()‎ و pop()‎ في تعقيد زمني خطي، ولمّا كانت الخوارزمية تجري مسحًا على جميع الحروف في التعبير المعطى مرة واحدة فإنّ التعقيد الزمني لهذه الخوارزمية خطّي ويبلغ المقدار O(n)‎.

مصادر