• 0
Dr.Robert

تحويل الأعداد من صيغة رقمية الى حرفية

سؤال

السلام عليكم

خلال اليوميين الماضيين كنت غير مشغول وتقريبا "فاضي" تماما واشعر بالملل. وبدأت اقلب في اشياء واوراق قديمة

وقعت في يدي فاتورة قديمة ولاحظت أن المبلغ المسجل في الفاتورة (بشكل يدوي) مكتوب رقما وكتابة (سبحان الله) قد يقول البعض ولكن حلمكم علي شوي.

بدأت افكر : كيف استطيع ترجمة رقم مثل 17 الى "سبعة عشر" في برنامج؟

استحوذ الموضوع على إهتمامي وتركت ما في يدي , و امسكت ورقة وقلم وقعدت افكر واشخبط في شكل خوارزمية بسيطة.

ومع مرور الوقت تحولت من حبر على ورق الى Java class بسيط .

مبدأ الخوارزمية الذي توصلت له غير معقد بالمرة:

المدخل لهذة الخوارزمية هو عدد (بصورة رقمية مثل 123) .

تقوم الخوارزمية بمسح (scan) العدد من اقصى اليمين (خانة آحاد الوحدات) وصعودا الى اخر رقم في اقصى اليمين .

اثناء المسح وعند كل خانة يجب ان تتوفر للخوارزمية قيمتين , القيمة الاولى هي خانة العدد المقروء (احاد,عشرات ام مئات) , وكذلك القوة العشرية للموقع .

فمثلا واثناء المسح وجدنا العدد 2 في خانة العشرات , هذا يعني ان القيمة الحرفية لة هي "عشرون" بشكل مبدأي.

ومن خلال القوة العشرية لموقع الرقم نستطيع ان نعرف هل هي "عشرون" فقط ام "عشرون الف" ام "عشرون مليون" وهكذا.

القيم الحرفية الأساسية للأرقام , ستكون عبارة عن كلمات مخزونة ("صفر,واحد,اثنان.......,عشرة ,عشرون, ثلاثون....مائة ,الف, مليون...") . ومنها تستطيع الخوارزمية انشاء تركيبات حرفية مثل "سبعة عشرة الف و خمسة مائة".

تطبيق الخوارزمية برمجيا ليس معقدا. وبالإمكان تطبيقها بكود جميل وغير معقد.

ولكن.

بما أن اللغة العربية لها قواعد لغوية صارمة . نجد ان نص مثل "اثنان الف" غير مقبول قواعديا بل "الفان"

و نص مثل "اثنين عشرة" لا وجود لة في اللغة العربية بل "اثنا عشرة".

ولذلك كان لابد من محاولة إدخال "بعض" القواعد على الكود , فتحول الكود من كود Java الى شيء يشبة كود الC :huh: (مع كل التقدير لمبرمجي C).

وعلى العموم الموضوع بأكملة كان مثير ومنعش للعقل.

لا اطيل عليكم واترككم مع النتيجة النهائية وهي عبارة عن فئة تحوي دالة واحدة فقط public static تأخذ متغير واحد من نوع Number وتعيد String

وهي صالحة للأعداد الموجبة والسالبة وكذلك الكسور

ملحوظة للأخ علاء الصالحي:

قرأت هنا او هناك انك قمت بتطوير حزمة خاصة بالأرقام العربية ,لم اراها حتى الان, ولكن مارأيك ان تقوم بتضمين الفئة هذه للحزمة؟ بعد تجربتها والتأكد من فائدتها إن شاء الله.

ArabicLiteralNumberParser.java

تم تعديل بواسطه Dr.Robert
5

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

129 إجابة على هذا السؤال .

  • 0

جاري تجربتها

شكرا لك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جزاكم الله خيرا

وجارى التجربه

معذره اخى علاء سوف اضع رابط الموضوع على مدونتك

اريد المساعده

حزمه مساعده باللغه العربيه

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

اخى انا رايى انك فنان

post-165385-12746338233284_thumb.png

الفئة تعمل بشكل جيد جدا مع كل انواع الارقام

وفعلا لها فائدة عظيمة جدا :clapping:

تحياتى

تم تعديل بواسطه MOHAMED FATHEI
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جربتها و فعلا رائعه

والحقيقة ان فكرة محمد فتحي اعجبتني، لما جربتها انا كنت اغير الرقم و اعمل run وكان الامر متعب.

ولكن هل جرتوا اضافة رقم بهذه الصورة 0011 (مالي خبره في testing) بس الموضوع جاء معي بالصدفة.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بجد بجد بجد شغل جميل جدا

انا فعلا كنت اجهل كيف استخدمها

فعندما وجدت اخى محمد فتحى قد استخدمها مع GUI

فقمت بذلك

wwwweq.jpg

ولكن لدى مشكله عندما ادخلت هذا الرقم

19399364990

فقد القى الى خطا ؟


Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "19399364990"

فهل من حل لذلك ؟

وعندما اخطات بالصدفه وادخلت حروف كذلك القى لى exception ?

هذا لا يقلل من شان العمل الجميل الاكثر من رائع شيئا

ولكنى اتعامل على اساس ان اتوقع اى مدخلات

بجد انا نفسى اعرف اتعملت ازاى :wacko: :wacko:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

+1

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ولكن هل جرتوا اضافة رقم بهذه الصورة 0011 (مالي خبره في testing) بس الموضوع جاء معي بالصدفة.

يكتب

احد عشر

فهو يتجاهل الصفر الذى على الشمال

انما ان كتبت له 000 فيكتب صفر مره واحده

وان كتبت +33 يلقى exception

وان كتبت 12.2 لا يكتب شىء كانه لم ياخذ ارقام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي حمزاوي

لا تستخدم gui

1- حاول ان تعدل الرقم من 19399364991 الى 19399364991d

ستجد ان القيمة العائدة صحيحة

2- عندما ادخلت حرف و حدث استثناء، فالاستثناء ليس من هذه الفئة بل من GUI عندما قمت بتويل القيمة المدخلة في JTextField الى رقم لأرسالة الى الطريقة literalValueOf

على اي حال لازلت ارى ان هذه الفئة رائعه ،،

تجربتي

في الصورة المرفقه قمت بادخال -13 وفعلا تعرف على علامة السالب

post-82434-12746376154216_thumb.gif

تم تعديل بواسطه العيافـي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي Dr.Robert

لماذا استخدمت Number ولم تستخدم double ا و long

هل هناك سبب معين ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي حمزاوي

لا تستخدم gui

1- حاول ان تعدل الرقم من 19399364991 الى 19399364991d

ستجد ان القيمة العائدة صحيحة

2- عندما ادخلت حرف و حدث استثناء، فالاستثناء ليس من هذه الفئة بل من GUI عندما قمت بتويل القيمة المدخلة في JTextField الى رقم لأرسالة الى الطريقة literalValueOf

على اي حال لازلت ارى ان هذه الفئة رائعه ،،

تمام

فهمت الخطأ

سورى خطا غير مقصود

وانا كنت معرف المتغير من نوع int

ولكن دلوقتى كل حاجه تمام

ممكن تعمل تشوف المدخلات +33 مثلا ؟ لماذا لم يتعرف على اشاره الموجب؟

فعلا جميله جدا

جزاك الله خيرا

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

البرنامج نجح معى فى كل الاختبارات

فى اختبار الاخ العيافى 0011

post-165385-12746387449173_thumb.png

وهذه النتيجة سليمة والا فما الخطأ فيها ؟

واختبار الاخ محمود

post-165385-12746388186411_thumb.png

ولم ينتج اى استثناء ربما نتج هذا الاستثناء لانك تحاول استخلاص رقم من نوع integer

من هذا الرقم الكبير جرب تحويله الى النوع Double ثم قم بارساله الى هذه الفئة

وبالنسبة للرقم 12.2

post-165385-12746390218428_thumb.png

لماذا لم يطبع عندك اى شئ ؟

تحياتى

تم تعديل بواسطه MOHAMED FATHEI
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي Dr.Robert

لماذا استخدمت Number ولم تستخدم double ا و long

هل هناك سبب معين ؟

اظن ليتمكن من تخزين حجم اكبر من الـ double , long

لان الـ Number هو الـ root object للـ int , double , float , long , short , ...

على حد علمى والله اعلم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

البرنامج نجح معى فى كل الاختبارات

فى اختبار الاخ العيافى 0011

وهذه النتيجة سليمة والا فما الخطأ فيها ؟

واختبار الاخ محمود

ولم ينتج اى استثناء ربما نتج هذا الاستثناء لانك تحاول استخلاص رقم من نوع integer

من هذا الرقم الكبير جرب تحويله الى النوع Double ثم قم بارساله الى هذه الفئة

وبالنسبة للرقم 12.2

لماذا لم يطبع عندك اى شئ ؟

تحياتى

فعلا كله تمام دلوقتى

وزى ما حضرتك قولت وانا كنت قولت قبل كدا انى استخدمت متغير من نوع integer

وطبعا بالنسبه للرقم 12.2 دا double

فيمكن يكون هذا هو الخطا

فعندما قمت بتغييره الى double كل شىء على ما يرام

شكراا

واسف خطا غير مقصود

سلام عليكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شكر جزيل للأخوة

مخمد فتحي , الحمزاوي , العيافي , والاخت يسرا

على تفاعلكم مع الموضوع و كلماتكم المشجعة.

احب ان اضيف لما قالة الأخ العيافي على تساؤلات للأخ حمزاوي انه لتتجنب حصول اخطاء بسبب نوع الرقم الذي يدخلة المستخدم في TextBox ,حول النص الى Double من خلال الدالة Double.valueOf() بدلا من Integer.valueOf() وبهذا الشكل ستضمن ان الاعداد الكبيرة والكسور سيتم قرائتها بشكل صحيح من TextBox وقبل إستدعاء الدالة literalValueOf.

اما بالنسبة للحروف فيجب ان تجبر المستخدم بطريقة ما على عدم ادخال حروف لأن ذلك سيؤدي للدالة Double.valueOf() بأن تطلق خطأ.

بالنسبة لسؤال الاخ العيافي , الغرض من الدالة هو ان تقرأ الأرقام بأنواعها المختلفة فلو اقتصر الأمر على Long مثلا لما امكن قراءة الاعداد الكسرية لأن Long هو للأعداد الصحيحة.

داخليا (وهذا سر :lol: )- الدالة غير قادرة إلا على ترجمة الارقام الصحيحة (غير الكسرية ) يعني Long فقط ولترجمة الاعداد الكسرية فإنها تقوم يترجمة العدد كجزئين منفصلين كل جزء كعدد صحيح Long وبعد ذلك تضبط النص النهائي قبل إرسالة للمستخدم.

طبعا هذه العملية تتم بمعزل عن المستخدم الذي لا يعرف سوى النتيجة النهائية وبالنسبة لة الدالة صالحة مع جميع الارقام كسرية وغير كسرية.

لذلك من الناحية التصميمية يجب ان يكون المدخل Number .

لذلك اكبر قيمة تستطيع الدالة قرائتة هو اكبر عدد Long اي Long.MAX_VALUE ,قم بتمرير قيمة اكبر منة مثل Float.MAX_VALUE او Double.MAX_VALUE وشاهد النتيجة

السبب في إكتفائي بLong.MAX_VALUE هو انه لن تكون هناك حاجة لترجمة رقم اكبر (من الناحية المنطقية) , حتى ان تلك القيمة هي اساسا خيالية جدا .

ردي السابق متأخر بعض الشيء :lol:

وشكر اخر للأخ محمد فتحي على النتائج المعروضة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شكر جزيل للأخوة

مخمد فتحي , الحمزاوي , العيافي , والاخت يسرا

على تفاعلكم مع الموضوع و كلماتكم المشجعة.

وشكر اخر للأخ محمد فتحي على النتائج المعروضة

اخى العزيز انت تشكرنا على تشجيعنا وعرض النتائج

فماذا نقول لك وانت صاحب هذا المشروع الرائع ؟

بصراحة سيكون اضافة قوية لبرنامجى اذا سمحت لى باستخدامه طبعا :happy:

تحياتى

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
اخى العزيز انت تشكرنا على تشجيعنا وعرض النتائج

من حقي ان اشكرك :lol: فمن النادر ان تجد شخص يأخذ من وقتة ليجري تجارب على عمل ما واستكشاف خصائصة وعيوبة بهذة الجدية والسرعة.

(إسألني أنا , فأكثر عيوب البرامج يرجع لعدم وجود اختبارات جادة وشاملة من قبل أشخاص عندهم الشغف الكافي والإهتمام ).

هذا وإن دل فإنه يدل على ان العمل وجد طريقة السليم من خلال مبرمجين -قد يكونوا صغار السن- ولكن عندهم حس مهني عالي نفتقدة في اوساط العمل. :) إلى الأمام دائما.

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

الصراحة الموضوع شيق جدا جدا

أنا متوقف عن المشاركات الفترة دى عشان التزامات الكلية و مشايع و خلافه

أخلص بس و أوريكم ههههه

موضوه بجد رائع جدا أخ Dr.Robert

شكرا

تم تعديل بواسطه mr.beshoy
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي Dr.Robert وضح السبب مع اني لا استطيع ان احدد ايهما الافضل استخدام number ا و double سأحاول القرائة الشفرة كامله بتمعن .

عزيزي محمد فتحي عندما تدخل الرقم 0011 في حقل النص ثم تقوم بتحويله الى رقم فانه سيكون 11 لذلك لن تتمكن من تجربه الحاله التي ذكرتها انا،

لا احد يفهمني غلط : انا لا اريد التقليل من مقدار الجهد المبذول في هذا الصنف و لا اهميته ، ولكن هذه الحاله بالصدفه طلعت معي علما باني مقتنع و اجزم بانه لن يتم ارسال مثل هذا الرقم في برنامج حقيقي.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عمل يبدو مميز جدا, بارك الله فيك يا أخي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

لا احد يفهمني غلط :

عزيزى العيافى نعرف انك تتكلم بحسن نية و فى الصالح العام وكلنا كذلك

وصاحب الموضوع طرحه هنا للمناقشة والاستفادة من اراء وتجارب ذوى الخبرة مثلك

وفى الاخير نحن عائلة واحدة ولا ايه رايك؟

تحياتى

تم تعديل بواسطه MOHAMED FATHEI
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي العيافي سأحاول أن اشرح لك وجهة نظري في عدم إستخدام النوع double :

اذا قمت بتعريف النوع ك double فهذا يعني ضمنيا ان الدالة قادرة على التعامل مع اي رقم double من 0.0 ووصولا ل double.MAX_VALUE .

وهذا غير صحيح بالنسبة للدالة.

الرقم double يتضمن ارقام عملاقة جدا تعجز حتى منصة الجافا عن عرضها بالكامل بل تكتفي بإعطاء تمثيل رمزي لها ك "1.3e28" (هذا عدد عملاق جدا جدا ),

لترجمة مثل هذا الرقم نحتاج ان نعرف اولا ما هو ؟ بمعنى ان الحرف e هو تمثيل رياضي لا اعلم عنة شيئا سوى اسمة (expansion اذا لم تخني الذاكرة وهو حرف E الموجود في الآلة الحاسبة كما اعتقد).

وحتى اذا عرفنا ماهو وعرفنا ان شكل الرقم الأصلي هو شيء كهذا مثلا "4566579548672374623526352675647563785748957675868457"

فهكذا ارقام لن تجد احد يستخدمها إلا في العمليات الرياضية الفلكية او النووية او او .....وهي ليست ارقام لتعرض على مستخدم بشكل نصي وبأي لغة كانت.

اما الفئة التي نتكلم عنها , فلا علاقة لها بالعمليات الرياضية لا من قريب ولا من بعيد , الغرض منها فقط هو التمثيل النصي لرقم ليصبح مقروءا للمستخدم (ناحية جمالية او فنية تعطي المستخدم ثقة اكبر اثناء استخدام البرنامج .. الخ) .

الشيء الثاني متعلق - في نظري - بالمنطق الوظيفي للدالة .

double وfloat وinteger جميعها ارقام في النهاية وتم تقسيمها لفئات منفصلة "لأغراض رياضية بحتة" ويستخدم كل منها حسب الحاجة لة.

اذا حددنا نوع المتغير الذي تأخذة الدالة بأحد تلك الأنواع , فالدالة توحي وانها دالة رياضية من نوع ما وتتعامل مع نوع معين من الأرقام .

لا يكفي ان نقول ان double "هو اكبر الأنواع وشامل للبقية ولذلك استخدمناة" , لأنة في النهاية "نوع من الأرقام" واستخدامنا لة يجب ان يكون في سياق مقنع اكثر.

وبما أن جميع الأنواع هنا لا معنى لها بالنسبة للمستخدم (نظرا لوظيفة الدالة الغير رياضية) فالأنسب ان نتركها مجردة بإعتبارها دالة تتعامل مع numbers بشكل عام.

ومسألة أن يحاول المستخدم ان يجري عليها تجارب بأرقام خيالية هو امر وارد possible ولكن غير محتمل un-likely وبعيد عن الهدف من الدالة.

تم تعديل بواسطه Dr.Robert
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
لترجمة مثل هذا الرقم نحتاج ان نعرف اولا ما هو ؟ بمعنى ان الحرف e هو تمثيل رياضي لا اعلم عنة شيئا سوى اسمة (expansion اذا لم تخني الذاكرة وهو حرف E الموجود في الآلة الحاسبة كما اعتقد).

1.5e10 تعني :

1.5 * 10^10

1.5e-10 تعني :

1.5 * 10 ^ -10

هل تريد رأيي؟؟ إجعل عدة نسخ من هذه الدالة تتراكب فوق بعض (overloaded)

موضوع أن الدالة تأخذ متغير من نوع Number لم أره من قبل, فماذا لو جلعت أكثر من نسخه تأخذ أكثر من نوع long, int, short, double, float ...

مجرد رأي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

هل تريد رأيي؟؟ إجعل عدة نسخ من هذه الدالة تتراكب فوق بعض (overloaded)

موضوع أن الدالة تأخذ متغير من نوع Number لم أره من قبل, فماذا لو جلعت أكثر من نسخه تأخذ أكثر من نوع long, int, short, double, float ...

مجرد رأي

اؤيد الاخ هويدى فى هذا الرأى

على الاقل ستكون هذه الفئة طبيعية بالنسبة للمستخدم العادى

فمثلا فى ال netbeans فى خاصية autocomplete تظهر للمستخدم int long double وهكذا وهى اكثر اعتيادية more friendly للمستخدم

ولن يكلفك الموضوع الكثير مع استخدامك لل object-oriented programming وهو اسلوبك فى هذه الفئة

هذا مجرد رأى

تحياتى

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

هل تريد رأيي؟؟ إجعل عدة نسخ من هذه الدالة تتراكب فوق بعض (overloaded)

موضوع أن الدالة تأخذ متغير من نوع Number لم أره من قبل, فماذا لو جلعت أكثر من نسخه تأخذ أكثر من نوع long, int, short, double, float ...

مجرد رأي

معذرة على التدخل

فلماذا اجعل للداله اكثر من صوره ؟

ويوجد هناك بديل ياخذ كل تلك الانواع Number ؟

ممكن توضح اخى العزيز ما الفائده من وجهه نظرك

مجرد نقاش والله لا اكثر

اريد ان اعلم ما الفائده؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
ولن يكلفك الموضوع الكثير مع استخدامك لل object-oriented programming وهو اسلوبك فى هذه الفئة

ولكن لاحظ اننا لن نستطيع ان نضع دالة لل double للأسباب التي شرحتها سابقا.

والدالة ايظا تعجز عن ترجمة جميع الاعداد من نوع float (لأن Float.MAX_VALUE > Long.MAX_VALUE)

يعني الامر سيقتصر على دوال ل long وshort وinteger .

وبالتالي لا يمكن ترجمة للأعداد الكسرية . لأن الأنواع المذكورة هي للأعداد الصحيحة فقط

وهذة هي المعضلة.

الدالة قادرة على ترجمة جميع الاعداد(كسور وغير كسور) من 0 الى Long.MAX_VALUE

لا استطيع ان احدد نوعها ك float او double لأنهم اكبر من long ولا

استطيع ان احدد نوعها ك long لأنه اصلا لا يدعم الكسور .

يعني اذا كان هناك نوع اقل من float و في نفس حجم long ويدعم الكسور لأستخدمناه دون تردد

ولكن لأنة غير موجود فسنترك الدالة Number فقط (هذا رأيي فقط وارحب بأي مقترح يحل المعضلة)

اخي هويدي تبدو وسيما في الصورة (بدون مجاملة :lol: )

تم تعديل بواسطه Dr.Robert
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .