c++ tutorial




^=32 এর পিছনে ধারণাটি কী, যা ছোট হাতের অক্ষরগুলিকে উচ্চতর এবং বিপরীতভাবে রূপান্তর করে? (7)

32 (00100000 বাইনারি মধ্যে) সঙ্গে Xoring সেট বা ষষ্ঠ বিট (ডান থেকে) রিসেট। এটি 32 যোগ বা বিয়োগ করার সমানভাবে সমান।

আমি codeforces কিছু সমস্যা সমাধানের ছিল। সাধারণত আমি প্রথম অক্ষরটি উপরের বা নীচের ইংরাজী অক্ষরটি পরীক্ষা করে দেখি, এটি বিয়োগ বা 32 যুক্ত অক্ষরে রূপান্তর করতে যুক্ত করুন। কিন্তু আমি কেউ একই জিনিস করতে ^= 32 খুঁজে পেয়েছি। এটা এখানে:

char foo = 'a';
foo ^= 32;
char bar = 'A';
bar ^= 32;
cout << foo << ' ' << bar << '\n'; // foo is A, and bar is a

আমি এর জন্য একটি ব্যাখ্যা অনুসন্ধান করেছি এবং খুঁজে পাইনি। তাহলে কেন এটা কাজ করে?


আমাকে এই বলে বলতে অনুমতি দিন - যদিও এটি স্মার্ট মনে হচ্ছে - একটি সত্যিই, সত্যিই মূঢ় হ্যাক। যদি কেউ 2019 সালে আপনার কাছে এটি সুপারিশ করে, তাকে আঘাত করুন। আপনি যত তাড়াতাড়ি তাকে আঘাত করতে পারেন।
আপনি অবশ্যই আপনার নিজের সফটওয়্যারে এটি করতে পারেন যে আপনি এবং অন্য কেউ যদি ব্যবহার করেন না তবে আপনি যদি কোনও ভাষা ব্যবহার করেন তবে ইংরাজী ব্যবহার করবেন না। অন্যথায়, যেতে না।

হ্যাকটি 30-35 বছর আগে বিতর্কিত "ঠিক আছে" যখন কম্পিউটারগুলি আসলেই অনেক কিছু করেনি তবে ইংরেজি ভাষায় ASCII তে এবং সম্ভবত এক বা দুটি প্রধান ইউরোপীয় ভাষা ছিল। কিন্তু ... আর তাই না।

হ্যাক কাজ করে কারণ মার্কিন-ল্যাটিন ঊর্ধ্ব- এবং 0x20 একে অপরের থেকে ঠিক 0x20 হয় এবং একই 0x20 উপস্থিত হয়, যা কেবলমাত্র একটি বিট পার্থক্য। যা, আসলে, এই বিট হ্যাক, toggles।

এখন, পশ্চিমা ইউরোপের কোড কোডগুলি এবং পরবর্তীতে ইউনিকোড কনসোর্টিয়াম ব্যবহারকারীরা এই প্রকল্পটিকে জার্মান জার্মান উমলটস এবং ফ্রেঞ্চ-অ্যাকসেন্টেড ওয়ারলেস রাখার জন্য যথেষ্ট স্মার্ট ছিল। তাই না এমন কোনটি (যা কেউ ২017 সালে ইউনিকোড কনসোর্টিয়ামকে বিশ্বাস করে না এবং এটি সম্পর্কে একটি বড় জাল নিউজ মুদ্রণ পত্রিকা লিখেছিল, আসলে ডুডেনকে দৃঢ়ভাবে বিশ্বাস করেছিল - কোনও মন্তব্য নেই) এটি একটি বনাম (এসএস রূপান্তর) হিসাবেও বিদ্যমান নেই। । এখন এটি 0x1DBF হিসাবে বিদ্যমান, কিন্তু দুটি 0x1DBF অবস্থান পৃথক, 0x20 নয়।

বাস্তবায়নকারীরা এই চলতে থাকায় যথেষ্ট বিবেচ্য ছিল না। উদাহরণস্বরূপ, যদি আপনি কিছু পূর্ব ইউরোপীয় ভাষাগুলিতে বা আপনার মতামতটি (আমি সিরিলিক সম্পর্কে জানতাম না) আপনার হ্যাক প্রয়োগ করি তবে আপনি একটি বিস্ময়কর অবাক হবেন। যে সমস্ত "hatchet" অক্ষর তার উদাহরণ, ছোট হাতের অক্ষর এবং বড় হাতের অক্ষর পৃথক। হ্যাক এইভাবে সঠিকভাবে কাজ করে না

বিবেচনা করার জন্য আরো অনেক কিছু আছে, উদাহরণস্বরূপ, কিছু অক্ষর কেবলমাত্র ছোট থেকে বড় হাতের অক্ষরে রূপান্তর করে না (তারা বিভিন্ন ক্রম অনুসারে প্রতিস্থাপিত হয়), অথবা তারা ফর্ম পরিবর্তন করতে পারে (বিভিন্ন কোড পয়েন্টগুলির প্রয়োজন)।

এই হ্যাকটি থাই বা চীনা মত স্টাফে কী করবে তা নিয়েও চিন্তা করবেন না (এটি আপনাকে কেবল সম্পূর্ণ অর্থহীন করে দেবে)।

কয়েক শত সিপিও চক্র সংরক্ষণ করা 30 বছর আগে খুব উপযুক্ত হতে পারে, কিন্তু আজকাল, একটি স্ট্রিং সঠিকভাবে রূপান্তর করার জন্য সত্যিই কোন অজুহাত নেই। এই অ-তুচ্ছ কাজ সম্পাদনের জন্য লাইব্রেরি ফাংশন আছে।
বেশ কয়েক ডজন কিলোবাইট টেক্সট সঠিকভাবে রূপান্তরিত করার সময় আজকাল নগণ্য।


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

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

https://en.wikipedia.org/wiki/Bitwise_operation

সাধারণ কম খরচে প্রসেসরগুলিতে, সাধারণত, বিটwise অপারেশনগুলি বিভাগের তুলনায় উল্লেখযোগ্যভাবে দ্রুত, গুণমানের চেয়ে অনেক গুণ দ্রুত এবং কখনও কখনও উল্লেখের চেয়ে উল্লেখযোগ্যভাবে দ্রুত।

দ্রষ্টব্য: আমি কয়েকটি কারণে (পঠনযোগ্যতা, সঠিকতা, পোর্টেবিলিটি, ইত্যাদি) জন্য স্ট্রিংগুলির সাথে কাজ করার জন্য আদর্শ লাইব্রেরি ব্যবহার করার সুপারিশ করব। আপনি কর্মক্ষমতা পরিমাপ করা হলে শুধুমাত্র বিট flipping ব্যবহার করুন এবং এই আপনার bottleneck হয়।


এটি কাজ করে কারণ, এটি ঘটেছে, ASCII এবং প্রাপ্ত এনকোডিংগুলিতে 'a' এবং 'A' এর মধ্যে পার্থক্য 32 এবং 32 হল 6 ষ্ঠ বিটের মান। একটি একচেটিয়া সঙ্গে 6 র্থ বিট flipping বা এইভাবে উপরের এবং নিম্নের মধ্যে রূপান্তর।


এর বাইনারি এ ASCII কোড টেবিল একটি চেহারা নিতে দিন।

A 1000001    a 1100001
B 1000010    b 1100010
C 1000011    c 1100011
...
Z 1011010    z 1111010

এবং 32 হল 0100000 যা ছোট হাতের এবং বড় হাতের অক্ষরগুলির মধ্যে একমাত্র পার্থক্য। তাই যে বিট টগল একটি চিঠি ক্ষেত্রে toggles।


সম্ভবত অক্ষর সেট আপনার বাস্তবায়ন ASCII হবে। আমরা টেবিলে তাকান যদি:

আমরা দেখতে পাচ্ছি যে ছোট হাতের অক্ষর এবং বড় হাতের অক্ষরের মানের মধ্যে ঠিক 32 পার্থক্য রয়েছে। অতএব, যদি আমরা ^= 32 (যা 6 ষ্ঠ কমপক্ষে উল্লেখযোগ্য বিট টগল করার সমান) করে, এটি একটি ছোট হাতের অক্ষর এবং বড় অক্ষরের মধ্যে পরিবর্তিত হয়।

মনে রাখবেন যে এটি শুধুমাত্র অক্ষর নয়, সমস্ত প্রতীকগুলির সাথে কাজ করে। এটি 6 র্থ বিট ভিন্ন যেখানে সংশ্লিষ্ট চরিত্রের সাথে একটি চরিত্রকে টগল করে, যার ফলে অক্ষরের একটি জোড়া জোড়া হয় যা পরবর্তীতে টগল করে। অক্ষরের জন্য, সংশ্লিষ্ট উপরের / ছোট হাতের অক্ষর যেমন একটি জোড়া গঠন। একটি NUL Space এবং অন্য দিকে প্রায় পরিবর্তিত হবে, এবং @ ব্যাক্টিকের সাথে Toggles। মূলত এই চার্টের প্রথম কলামের যেকোনো অক্ষর চরিত্রের এক কলামের সাথে টগল করে এবং একইটি তৃতীয় এবং চতুর্থ কলামগুলিতে প্রযোজ্য।

যদিও আমি এই হ্যাক ব্যবহার করব না, যেহেতু এটি কোনও সিস্টেমে কাজ করার নিশ্চয়তা দেয় না। শুধু পরিবর্তে toupper এবং tolower ব্যবহার করুন, এবং যেমন isupper হিসাবে প্রশ্ন।


নিম্ন-কেস এবং উচ্চ-কেস বর্ণমালা রেঞ্জ ASCII কোডিং সিস্টেমে %32 "সারিবদ্ধকরণ" সীমানা অতিক্রম করে না।

এই কারণে বিট 0x20 একই অক্ষরের উপরের / নিম্ন ক্ষেত্রে সংস্করণগুলির মধ্যে একমাত্র পার্থক্য।

যদি এটি না হয় তবে আপনাকে 0x20 যোগ করতে বা বিয়োগ করতে হবে, শুধু টগল নয়, এবং কিছু অক্ষরগুলির জন্য অন্যান্য উচ্চতর বিটগুলিকে ফ্লিপ করতে হবে। (এবং একমাত্র অপারেশন যা টগল করতে পারে না এবং প্রথম স্থানে বর্ণানুক্রমিক অক্ষরগুলি পরীক্ষা করা কঠিন হবে কারণ আপনি করতে পারছেন না = = 0x20 ল্যকেস জোরদার করতে।)

সম্পর্কিত ASCII-only tricks: আপনি c |= 0x20 সাথে c |= 0x20 জোর করে একটি বর্ণানুক্রমিক ASCII চরিত্রের জন্য পরীক্ষা করতে পারেন এবং তারপরে (অ-স্বাক্ষরিত) c - 'a' <= ('z'-'a') । তাই 3 টি অপারেশন: OR + SUB + একটি ধ্রুবক 25 এর বিরুদ্ধে সিএমপি। অবশ্যই, কম্পাইলারগুলি আপনার জন্য এটির মতো (c>='a' && c<='z') কীভাবে অপ্টিমাইজ করবেন তা জানেন , তাই আপনাকে অবশ্যই c|=0x20 অংশটি নিজে করুন। সমস্ত প্রয়োজনীয় কাস্টিং নিজেকে করতে অসুবিধাজনক, বিশেষ করে স্বাক্ষরিত int ডিফল্ট পূর্ণসংখ্যা প্রচারগুলির কাছাকাছি কাজ করার জন্য।

unsigned char lcase = y|0x20;
if (lcase - 'a' <= (unsigned)('z'-'a')) {   // lcase-'a' will wrap for characters below 'a'
    // c is alphabetic ASCII
}
// else it's not

সি ++ থেকে উচ্চ ক্ষেত্রে একটি স্ট্রিং রূপান্তর দেখুন (শুধুমাত্র ASCII এর জন্য সিমড স্ট্রিং toupper , যে চেক ব্যবহার করে XOR এর অপারেড মাস্কিং।)

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

এই কৌশলগুলি বেশিরভাগই কেবলমাত্র দরকারী তবে সিএমডি (যেমন SSE2 বা NEON) সহ কিছু পাঠ্য-প্রক্রিয়াকরণটি হ্যান্ড-অপ্টিমাইজ করার পরে, কোনও ভেক্টরের কোনও char মধ্যে তাদের কোনও উচ্চ বিট সেট থাকে না তা পরীক্ষা করার পরে। (এবং এইভাবে কোনও বাইট একক চরিত্রের জন্য মাল্টি-বাইট ইউটিএফ -8 এনকোডিংয়ের অংশ নয়, যা বিভিন্ন উচ্চ / নিম্ন-ক্ষেত্রে বিপরীত হতে পারে)। যদি আপনি কোনটি খুঁজে পান, তবে আপনি 16 বাইটের এই অংশে বা বাকি স্ট্রিংটির জন্য স্কলারে ফিরে যেতে পারেন।

এমনকি এমন কিছু স্থান রয়েছে যেখানে ASCII পরিসরের কিছু অক্ষরগুলিতে toupper() বা tolower() যে পরিসরের বাইরে অক্ষর উৎপন্ন করে, বিশেষ করে তুর্কি যেখানে আমি ↔ ı এবং İ ↔ i। সেই লোকেদের মধ্যে, আপনাকে আরো অত্যাধুনিক চেকের প্রয়োজন হতে পারে, অথবা সম্ভবত এই অপ্টিমাইজেশানটি ব্যবহার করার চেষ্টা করবেন না।

কিন্তু কিছু ক্ষেত্রে, আপনাকে UTF-8 এর পরিবর্তে ASCII অনুমান করার অনুমতি দেওয়া হয়, যেমন LANG=C (POSIX লোকেল) সহ ইউনিক্স ইউটিলিটি, en_CA.UTF-8 বা যাই হোক না কেন।

কিন্তু আপনি যদি এটির নিরাপদ যাচাই করতে পারেন তবে আপনি লুপ (5x এর মতো toupper() কলিং toupper() এর চেয়ে দ্রুত গতিতে মাঝারি দৈর্ঘ্যের স্ট্রিংগুলি toupper করতে পারেন এবং শেষ পর্যন্ত আমি বুস্ট 1.58 দিয়ে পরীক্ষা করেছি, বুস্ট boost::to_upper_copy<char*, std::string>() চেয়ে অনেক বেশি দ্রুত boost::to_upper_copy<char*, std::string>() যা প্রতিটি চরিত্রের জন্য একটি মূঢ় dynamic_cast করে।





ascii