`C> = '0' বা` সি> = 48` পরীক্ষা করা কি ভাল?


46

আমার কয়েকজন সহকর্মীর সাথে আলোচনার পরে, আমি সর্বোত্তম অনুশীলনগুলি অনুসরণ করে জাভাতে চর ডেটা টাইপকে কীভাবে আচরণ করব সে সম্পর্কে একটি 'দার্শনিক' প্রশ্ন

ধরুন একটি সাধারণ দৃশ্য (স্পষ্টতই এটি আমার প্রশ্নের একটি অনুশীলনকে অর্থ দেওয়ার জন্য খুব সহজ উদাহরণ) যেখানে স্ট্রিংয়ের ইনপুট হিসাবে দেওয়া হয়েছে, আপনাকে এতে উপস্থিত সংখ্যার অক্ষরের সংখ্যা গণনা করতে হবে।

এটি 2 সম্ভাব্য সমাধান:

1)

    for(int i=0; i<s.length(); i++) {
        if(s.charAt(i) >= 48 && s.charAt(i) <= 57) {
            n++;
        }
    }

2)

    for(int i=0; i<s.length(); i++) {
        if(s.charAt(i) >= '0' && s.charAt(i) <= '9' ) {
            n++;
        }
    }

দুজনের মধ্যে কোনটি আরও 'পরিষ্কার' এবং জাভা সেরা অনুশীলনের সাথে অনুগত?


141
আপনি যখন '0' এবং '9 'বলতে চান তবে আপনি 48 এবং 57 লিখবেন কেন? শুধু আপনি কি বলতে চান তা লিখুন।
ব্র্যান্ডিন

9
আপনি কী করছেন তা অপেক্ষা করুন, জাভাতে VK_আপনার ব্যবহারের ধ্রুবকগুলি রয়েছে , দ্বিতীয়ত চর কোডগুলি ব্যবহার করা চরের চেয়ে ভাল যা জাভা এমন এক সুরক্ষিত ভাষা যা আপনার ক্রস-টাইপ চেকিংয়ের কথা নয়। @ ব্র্যান্ডিনকে এগুলি কোডিং অনুশীলন বলা হয়
মার্টিন বার্কার

12
এই 6 জন ব্যক্তির বিচার করার চেয়ে বেশি কিছু করার বিরক্তি ছাড়াই এই উত্তম প্রশ্ন। আপনি সংখ্যা হিসাবে চর ব্যবহার করছেন? যদি তাই সংখ্যা ব্যবহার করুন। আপনি কি এটি চিঠি হিসাবে ব্যবহার করছেন? যদি তাই হয় অক্ষর ব্যবহার।
অ্যালেক টেলি

17
@ মার্টিন বার্কার VK_*ধ্রুবকগুলি অক্ষরের সাথে নয় কীগুলির সাথে সম্পর্কিত ।
কোডসইনচাউস

2
আপনার প্রশ্নের সাথে এই কোডটি কী করে তা নির্ধারণ করতে আমার কয়েক মিনিট সময় লেগেছে। ইতিমধ্যে এটি স্পষ্ট নয় কারণ এটি ধরে নিয়েছে যে আমি (1) এ জানি যে আমি জানি যে এটি আইএসও-লাতিনের 1 এর ডিজিটের পরিসীমা So সুতরাং এটি রক্ষণাবেক্ষণের দিক থেকে সমস্যাযুক্ত করে তোলে।
সাইবারস্কুল

উত্তর:


124

দুটোই ভয়ঙ্কর, তবে প্রথমটি আরও ভয়ঙ্কর।

উভয় জাভা অন্তর্নির্মিত ক্ষমতা "সংখ্যাসমূহ" (পদ্ধতিগুলির মাধ্যমে Character) কী তা সিদ্ধান্ত নিতে পারে তা উপেক্ষা করে । কিন্তু প্রথম এক না শুধুমাত্র স্ট্রিং ইউনিকোড প্রকৃতি উপেক্ষা করে অভিমানী হতে পারে যে শুধুমাত্র 0123456789, এটা এছাড়াও চরিত্র কোড যে জানার জন্য শুধুমাত্র আপনি এনকোডিং অক্ষর এর ইতিহাস সম্পর্কে কিছু জানেন ব্যবহার করে এমনকি এই অবৈধ যুক্তি obscures।


33
আপনি কেন ধরে নিচ্ছেন যে অ-এএসসিআইআই নম্বরগুলি প্রত্যাখ্যান করা ভুল নয়? এটি প্রসঙ্গে নির্ভর করে।
কোডসইনচাউস

21
@ কোডসইনচাউস যদি আপনি সত্যিই সংখ্যাসূচক অক্ষরগুলি সন্ধান করতে চান তবে 0123456789 এর জন্য স্ক্যান করা সহজ ভুল। আপনি যদি কেবল এই দশটি অক্ষরের জন্য স্ক্যান করতে চান তবে তা মূলত অর্থহীন টোকেন যা কেবল দুর্ঘটনাক্রমে কেবল এএসসিআইআই / আইএসও-ল্যাটিন জানেন এমন লোকদের জন্য পরিচিত বলে মনে হয়। এর সাথে কোনও ভুল নেই - আমাকে প্রায়শই সুনির্দিষ্টভাবে করতে হয়, উদাহরণস্বরূপ উত্তরাধিকারী সফ্টওয়্যারটির সাথে ইন্টারঅ্যাক্ট করতে যা সত্যিই কেবল এই দশটি চরিত্রকেই গ্রহণ করে না। তবে তারপরে matches("[0-9]+")youতিহাসিকভাবে অনুপ্রাণিত রেঞ্জ ট্রিকের পরিবর্তে এর মতো কিছু ব্যবহার করে আপনার উদ্দেশ্যগুলি স্পষ্ট করা উচিত ।
কিলিয়ান ফট

15
আছে পুরো প্রস্থ সংখ্যা , যা হওয়া ASCII সংখ্যা হিসাবে একই মত চেহারা, এবং সফটওয়্যার সাধারণ অনেক তাদের হওয়া ASCII ডিজিটের জায়গায় গ্রহণ করার প্রয়োজন হয়। (স্পষ্টতই "প্রচুর" সংজ্ঞা অনুসারে প্রচুর সফ্টওয়্যার নষ্ট হয়ে গেছে You আপনি সহজেই বলতে পারবেন কারণ এক দেশের সফটওয়্যার বিক্রেতারা অন্য দেশে বিক্রি করা অসম্ভব বলে মনে করেন কারণ বিক্রেতারা অন্যান্য দেশের প্রয়োজনীয়তা সম্মান করে না। )
রওয়ং

37
Have a Japanese IME installed , and accidentally type in full width all all the time
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

14
"উভয়ই ভয়াবহ", তবে আপনি সঠিক সমাধানটি বলতে ভুলে গেছেন ;-)
ক্রোমস্টার বলেছেন মোনিকার

163

আমরাও। জাভা অন্তর্নির্মিত অক্ষর শ্রেণিটি এটি খুঁজে বের করুক figure

for (int i = 0; i < s.length(); ++i) {
  if (Character.isDigit(s.charAt(i))) {
    ++n;
  }
}

ASCII সংখ্যাগুলির চেয়ে আরও কয়েকটি চরিত্রের ব্যাপ্তি রয়েছে যা অঙ্ক হিসাবে গণনা করা হয় এবং আপনি পোস্ট করেছেন এমন দুটি উদাহরণই সেগুলি গণনা করবে না। JavaDoc জন্য Character.isDigit()তালিকা বৈধ সংখ্যা হচ্ছে এই চরিত্র রেঞ্জ:

কিছু ইউনিকোড চরিত্রের ব্যাপ্তিগুলিতে ডিজিট থাকে:

  • '\ u0030' এর মাধ্যমে '\ u0039', আইএসও-ল্যাটিন -১ ডিজিট ('0' মাধ্যমে '9')
  • '\ u0660' এর মাধ্যমে '\ u0669', আরবি-ইন্দিক ডিজিট
  • '\ u06F9' এর মাধ্যমে '\ u06F0', প্রসারিত আরবি-ইন্ডিক অঙ্কগুলি
  • '\ u096F' এর মাধ্যমে '\ u0966', দেবনাগরী অঙ্কগুলি
  • '\ uFF10' এর মাধ্যমে '\ uFF19', পূর্ণ দৈর্ঘ্যের অঙ্কগুলি

অন্যান্য অনেকগুলি চরিত্রের ব্যাপ্তিতে ডিজিটও রয়েছে।

বলা হচ্ছে, Character.isDigit()এই তালিকার সাথে একজনেরও প্রতিনিধি হওয়া উচিত । নতুন ইউনিকোড বিমানগুলি জনবহুল হওয়ায় জাভা কোডটি আপডেট হবে। জেভিএম আপগ্রেড করা পুরানো কোডটি নির্বিঘ্নে নতুন অঙ্কের অক্ষরের সাথে কাজ করতে পারে। এটি ডিআরওয়াইও : অন্য যে কোনও জায়গায় রেফারেন্সযুক্ত কোনও স্থানে "এটি কি এই অঙ্কের" কোড স্থানীয়করণের মাধ্যমে কোডের সদৃশতার (যেমন বাগ) নেতিবাচক দিকগুলি এড়ানো যায়। শেষ অবধি, সর্বশেষ লাইনটি নোট করুন: এই তালিকাটি সম্পূর্ণ নয় এবং অন্যান্য সংখ্যাও রয়েছে।

ব্যক্তিগতভাবে, আমি বরং মূল জাভা গ্রন্থাগারগুলিতে প্রতিনিধিত্ব করব এবং "অঙ্কটি কী তা নির্ধারণ করার চেয়ে" বেশি সময় উত্পাদনশীল কাজে ব্যয় করব।


এই নিয়মের একমাত্র ব্যতিক্রম হ'ল যদি আপনাকে সত্যিকার অর্থে আক্ষরিক ASCII সংখ্যাগুলির পরীক্ষা করতে হয় অন্য সংখ্যার জন্য না । উদাহরণস্বরূপ, আপনি যদি কোনও স্ট্রিমটি বিশ্লেষণ করছেন এবং কেবলমাত্র ASCII ডিজিটের (অন্যান্য অঙ্কগুলির বিপরীতে) বিশেষ অর্থ রয়েছে, তবে এটি ব্যবহার করা উপযুক্ত হবে নাCharacter.isDigit()

MyClass.isAsciiDigit()সেক্ষেত্রে আমি অন্য একটি পদ্ধতি লিখব, উদাহরণস্বরূপ এবং সেখানে যুক্তি যুক্ত করব। আপনি কোড পুনঃব্যবহারের একই সুবিধাগুলি পান, নামটি যা চেক করছে সে সম্পর্কে এটি স্পষ্টভাবে পরিষ্কার এবং যুক্তিটি সঠিক।


4
প্রকৃত কোডটি যা কৌশলটি করে তা সরবরাহ করার জন্য দুর্দান্ত উত্তর।
পিয়ের আরলাড

27

আপনি যদি সি-তে এমন কোনও অ্যাপ্লিকেশন লিখেন যা EBCDIC কে মৌলিক চরিত্র সেট হিসাবে ব্যবহার করে 48এবং ASCII অক্ষরগুলি প্রক্রিয়া করতে হবে তবে ব্যবহার করুন এবং 57। আপনি কি করছেন? আমি তাই মনে করি না.

ব্যবহার সম্পর্কে isDigit(): এটি নির্ভর করে। আপনি কি JSON পার্সার লিখছেন? শুধু 0থেকে 9ডিজিটের বলে মেনে নেওয়া হয়েছে, তাই ব্যবহার করবেন না isDigit(), জন্য চেক >= '0'এবং <= '9'। আপনি কি ব্যবহারকারী ইনপুট প্রক্রিয়াজাত করছেন? আপনার isDigit()বাকি কোডটি যতক্ষণ ব্যবহার করুন প্রকৃতপক্ষে স্ট্রিংটি পরিচালনা করতে পারে এবং এটিকে সঠিকভাবে একটি সংখ্যায় পরিণত করতে পারে।


3
আসলে আপনি জাভাতে অ্যাপ্লিকেশন লিখতে পারেন যা EBCDIC পায় এবং ফেরত দেয়। এটা কোন মজা।
থরবজর্ন রাভন অ্যান্ডারসন

অনুরূপ 'মজা নেই' কোডটি অতিক্রম করছিল যা EBCDIC অক্ষরগুলির দশমিক মানগুলি ক্রস-প্ল্যাটফর্ম পরিবেশে রূপান্তর করার সময় ব্যবহার করে লেখা হয়েছিল ...
Gwyn ইভান্স

1
আপনি যদি জাভাতে EBCDIC ডেটা প্রক্রিয়াকরণ করছেন তবে অক্ষর হিসাবে প্রক্রিয়া করার আগে আপনার সম্ভবত এটি জাভা নেটিভ ইউটিএফ -16 অক্ষরে রূপান্তর করা উচিত। তবে আমি অনুমান করি যে প্রয়োগটি আসলেই নির্ভর করে; আশা করি আপনার প্রোগ্রামটি যদি EBCDIC এর সাথে ডিল করতে হয় তবে আপনি বুঝতে হবে কী করা দরকার।
মাইকেল

1
মূল বিষয়টি হ'ল জাভাতে EBCDIC প্রক্রিয়াকরণের জন্য '0' এবং 48 উভয়ই একটি অঙ্ক শূন্য সনাক্ত করতে ভুল । আরও বর্তমান, সি, সি ++ ইত্যাদিতে '\ n' এবং '\ r' বাস্তবায়ন সংজ্ঞায়িত করা হয়েছে তাই যদি আপনি উইন্ডোজবিহীন সংকলক ব্যবহার করে কোনও ফাইলের মধ্যে একটি উইন্ডোজ সিআর / এলএফ জোড় সনাক্ত করতে চান তবে এর পরিবর্তে দশমিক মানগুলি আরও ভাল করে পরীক্ষা করুন '\ n' এবং '\ r' এর জন্য পরীক্ষা করা হচ্ছে।
gnasher729

12

দ্বিতীয় উদাহরণটি পরিষ্কারভাবে উচ্চতর। দ্বিতীয় উদাহরণটির অর্থ তত্ক্ষণাত স্পষ্ট হয় যখন আপনি কোডটি দেখেন। প্রথম উদাহরণটির অর্থ কেবল তখনই স্পষ্ট হয় যদি আপনি আপনার মাথার পুরো এএসসিআইআই টেবিলটি মুখস্থ করে রেখেছেন।

আপনার একটি নির্দিষ্ট চরিত্রের জন্য পরীক্ষা করা, বা বর্ণের শ্রেণি বা শ্রেণির জন্য পরীক্ষা করা উচিত।

1) একটি নির্দিষ্ট চরিত্রের জন্য পরীক্ষা করা for

সাধারণ অক্ষরের জন্য, অক্ষর অক্ষর ব্যবহার করুন, উদাহরণস্বরূপ if(ch=='z')...,। আপনি যদি ট্যাব বা লাইন ব্রেকের মতো বিশেষ অক্ষরের বিরুদ্ধে পরীক্ষা করেন তবে আপনার পছন্দ মতো পালানো উচিত if (ch=='\n')...। আপনি যে চরিত্রটির জন্য যাচাই করছেন তা যদি অস্বাভাবিক হয় (যেমন তাৎক্ষণিকভাবে সনাক্তযোগ্য বা একটি আদর্শ কীবোর্ডে উপলব্ধ নয়) তবে আপনি আক্ষরিক অক্ষরের পরিবর্তে একটি হেক্স অক্ষর কোড ব্যবহার করতে পারেন। তবে যেহেতু একটি হেক্স কোডটি "ম্যাজিক মান", আপনি এটি একটি ধ্রুবক থেকে বের করে এটিকে নথিভুক্ত করবেন:

const char snowman = 0x2603; // snowman char used to detect encoding issues
...
if (ch==showman)...

হেক্স কোডগুলি চরিত্রের কোডগুলি নির্দিষ্ট করার মানক উপায়।

2) একটি অক্ষর শ্রেণি বা ব্যাপ্তি পরীক্ষা করা হচ্ছে

আপনার অ্যাপ্লিকেশন কোডটিতে সরাসরি এটি করা উচিত নয়, তবে কেবল অক্ষর শ্রেণিবিন্যাসের সাথে সম্পর্কিত এটি একটি পৃথক শ্রেণিতে আবদ্ধ করা উচিত। এবং আপনার এটির ভিন্ন হওয়া উচিত, যেহেতু গ্রন্থাগারগুলি ইতিমধ্যে এই উদ্দেশ্যে উপস্থিত রয়েছে এবং চরিত্রের শ্রেণিবিন্যাস সাধারণত আপনি যতটা ভাবেন তার চেয়ে জটিল হয়, যদি আপনি ASCII- সীমার বাইরে অক্ষরগুলি বিবেচনা করেন তবে।

আপনি যদি কেবল এএসসিআইআই রেঞ্জের অক্ষর সম্পর্কে উদ্বিগ্ন হন তবে আপনি এই লাইব্রেরিতে অক্ষর অক্ষর ব্যবহার করতে পারেন, অন্যথায় আপনি সম্ভবত হেক্স-লিটারাল ব্যবহার করতে পারেন। আপনি যদি জাভা বিল্টিন চরিত্রের লাইব্রেরির উত্স কোডটি দেখেন তবে এটি হেক্সাডেসিমাল ব্যবহার করে চরিত্রের মান এবং ব্যাপ্তিগুলিকেও বোঝায়, যেহেতু ইউনিকোড স্ট্যান্ডার্ডে এগুলিই নির্দিষ্ট করা হয়।


1
আমি হেক্সে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে লিখার পরামর্শ দিয়েছিলাম '\x2603'যাতে আপনি হেক্সাডেসিমাল এনকোডিংয়ের সাথে কোনও চরিত্রের জন্য মান পরীক্ষা করছেন এবং কেবল কোনও এলোমেলো সংখ্যা নয়।
wefwefa3

-4

এটি ব্যবহার করা সর্বদা ভাল c >= '0'কারণ c >= 48আপনার সি সি এসকি কোডে রূপান্তর করতে হবে।


3
এই উত্তরটি কী বলে যে এক সপ্তাহ আগে পূর্বের উত্তরগুলিতে ইতিমধ্যে বলা হয়নি?

-5

নিয়মিত এক্সপ্রেশন ( RegEx গুলি) এর অঙ্কগুলির জন্য নির্দিষ্ট বর্ণের শ্রেণি থাকে\d - যা আপনার স্ট্রিং থেকে অন্য কোনও অক্ষর অপসারণ করতে ব্যবহার করা যেতে পারে। ফলাফলযুক্ত স্ট্রিংয়ের দৈর্ঘ্য হ'ল কাঙ্ক্ষিত মান।

public static int countDigits(String str) {
    str = Objects.requireNonNull(str).trim();

    return str.replaceAll("[^\\d]", "").length();
}

তবে খেয়াল করুন যে RegEx গুলি অন্যান্য প্রস্তাবিত সমাধানগুলির তুলনায় গণ্যতামূলকভাবে বেশি দাবি করছে তাই তাদের সাধারণত পছন্দ করা উচিত নয়


চেক করতে খুব মার্জিত উপায়!
কেভিন রোবটেল

রেগেক্সগুলি এই জাতীয় কোনও কাজের জন্য ওভারকিল হয়
ফারাপ

2
@ স্টেফানোব্রাগাগলিয়া আপনার উত্তরটি পুনরায় পড়ার পরে আমার মনে হয় এটি সত্যই প্রশ্নের উত্তর দেয় না।
ফারাপ

2
আপনার উত্তরটি "আমি স্ট্রিংয়ে অঙ্কগুলি কীভাবে গণনা করব" এর সমস্যা সমাধানের একটি ভিন্ন উপায় সরবরাহ করে। এটি কোড নমুনা এবং ধ্রুবকের প্রতিনিধিত্ব সহ অন্তর্নিহিত ইস্যুটির উত্তর দেয় না - সংখ্যা বা অক্ষর হিসাবে।

2
এটি আসলে অঙ্কগুলি গণনা করে না (আপনি কেবল সমস্ত অঙ্ক সরিয়ে নেওয়ার পরে স্ট্রিংয়ের দৈর্ঘ্য কত তা বলে দেয়, যা এখানে বা সেখানে নেই) তবে আমি সম্মত হই যে এটি আসলে প্রশ্নের উত্তর দেয় না। উদাহরণস্বরূপ, উদাহরণস্বরূপ, স্ট্রিংগুলি থেকে অক্ষরগুলি সরানোর বিষয়ে কেউ জিজ্ঞাসা করছিল না। কোনও চরিত্রের সংখ্যাসূচক কিনা তা পরীক্ষা করার জন্য উপযুক্ত সর্বোত্তম অনুশীলনের উপায় সম্পর্কে প্রশ্নটি কেবল জিজ্ঞাসা করছে।
doppelgreener
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.