2011-01-25 15 views
6

में बिट्स की प्रत्येक जोड़ी के इस एक सवाल एक कैरियर मेले में एक NVIDIA प्रतिनिधि ने पूछा था:स्वैप बाइट

लिखें बाइट अंदर बिट्स की प्रत्येक जोड़ी स्वैप करने के लिए छोटे, कुशल कोड; उदाहरण के लिए, 10 11 01 1001 11 10 01 बनना चाहिए।

क्या अन्य सभी इंडेक्स के माध्यम से for लूप करके ऐसा करने के लिए कोई और "कुशल" तरीका है? मेरा कोड छोटा था, लेकिन मैं इस बारे में नहीं सोच सकता कि यह संभवतः एक लूप से कितना "कुशल" हो सकता है ... मुझे लगता है कि एक लूप से बचने के लिए एक्सओआर का उपयोग करने का कोई तरीका हो सकता है, लेकिन मैं नहीं कर सकता पता लगाओ।

धन्यवाद!

+0

यह 'एक सवाल wasn't'? मुझे यह नहीं लगता है ... –

+1

@MrDisappointment मुझे संदेह है कि यदि यह एक प्रश्न था, तो मेहरदद या तो एक लिखित समझौते का उल्लंघन करेगा या अन्य लोगों के साथ सवाल साझा नहीं करने का अनुरोध करेगा। – Phrogz

+0

@MrDisappointment: LOL क्षमा करें, टाइपो; निश्चित एक्सडी ... @ प्रागोग्स: ऐसा कोई समझौता या कुछ भी नहीं था, यह सौ या दो लोगों के साथ एक खुली करियर मेला था; कोई हस्ताक्षर या इस तरह के कुछ भी नहीं। :) – Mehrdad

उत्तर

11

आप 256-प्रविष्टि लुकअप तालिका का उपयोग कर सकते हैं।

वैकल्पिक रूप से, ((x & 0x55) << 1) | ((x & 0xAA) >> 1)

+0

+1। यदि यह गति आप चाहते हैं, तो लुकअप टेबल जवाब है। यह लुकअप टेबल के लिए 256 बाइट्स का उपयोग करता है, लेकिन अधिकांश अनुकूलन के साथ, यह एक स्पेस/टाइम ट्रेड-ऑफ है। यदि आप उस जगह को बर्बाद नहीं करना चाहते हैं, तो आप कुछ बदलावों और बिट ऑपरेशंस की तुलना में तेज़ होने की संभावना नहीं रखते हैं। – paxdiablo

+3

बेशक 'हस्ताक्षरित' प्रकार से सावधान रहें। –

+1

+1 मुझे लगता है कि यह दूसरा समाधान है, क्योंकि यह सबसे संक्षिप्त और बहुत ही कुशल है ... argh, इतना आसान और अभी तक इतना कठिन है। :( – Mehrdad

1

टेबल लुकअप (जब तक कि कोई विशेष एनवीआईडीए-विशिष्ट समाधान नहीं ढूंढ रहा था)।

+0

यह एक एनवीआईडीआईए-विशिष्ट समाधान की तलाश नहीं कर रहा था, लेकिन यह तेज़ * और * छोटा कोड ढूंढ रहा था ... क्या टेबल लुकअप समाधान गिनती होगी? (हालांकि स्वीकार्य रूप से मैंने इसके बारे में नहीं सोचा था ...) – Mehrdad

+0

@ मेहरदाद: टेबल लुकअप इस तरह की समस्याओं के साथ सिर्फ "पहली बात है जो दिमाग में आता है" है। निश्चित रूप से एक बेहतर, चालाक बिट हैक हो सकता है। आप एक समय में 4 बिट्स देखने के लिए कुछ शिफ्ट/मास्क ऑपरेशंस के साथ संयुक्त 16 बाइट (या यहां तक ​​कि 8 बाइट शायद) टेबल पर भी विचार कर सकते हैं। मुझे यकीन नहीं है कि मीठी जगह कहाँ हो सकती है। –

12

कुछ इस तरह सही करने के लिए 1 थोड़ा करके

(i >> 1) & 01010101 + (i << 1) & 10101010 

i >> 1 बदलाव सब कुछ काम करना चाहिए, और & 01010101 भी स्थिति में केवल बिट्स छोड़ देता है।
दूसरा भाग एक ही फेशन में अजीब बिट स्थिति के साथ सौदा करता है।

यह सुनिश्चित नहीं है कि यह कितना कुशल है।

+0

+1 यह डर्न चालाक है, धन्यवाद ... मैं बिट बदलावों का उपयोग करने के किसी तरीके के बारे में सोच रहा था लेकिन इसे समझ नहीं पाया। कूल !! :) – Mehrdad

+0

हाँ, मैं पसंद करता हूं | ऑपरेटर को ऑपरेटर लेकिन एक ही समाधान। और निश्चित रूप से बेस-2 प्रतिनिधित्व के लिए आपका कोड छद्म है। – CashCow

0

चूंकि बाइट में केवल 256 संभावित संयोजन हैं, इसलिए यह किसी भी समय लुकअप टेबल आधारित समाधान का उपयोग करने के लिए एक अच्छे उम्मीदवार की तरह लगता है जब निरंतर निष्पादन गति आंतरिक प्रीकंप्यूट और/या कुल स्मृति उपयोग से अधिक महत्वपूर्ण होती है।

उदाहरण के लिए:

lookupTable[00000000] = 00000000 
lookupTable[00000001] = 00000010 
lookupTable[00000010] = 00000001 
... 
+0

निश्चित रूप से छोटा कोड नहीं। :( – Mehrdad

+0

निश्चित रूप से मैं सहमत नहीं हूं, लेकिन याद रखें कि छोटा कोड हमेशा कुशल नहीं होता है और कुशल कोड हमेशा छोटा नहीं होता है। – Coxy

+0

कैश मिस सामान्य रूप से लुकअप टेबल के साथ एक समस्या है। इस छोटे से चीजों के लिए, परिणाम की गणना करना आसान है मुझे लगता है। –

2

लुकअप तालिका के बिना (या पहली जगह में बात उत्पन्न करने के लिए) आप भी कर सकते हैं:

  • पारी को छोड़ दिया और और वाम-बिट मुखौटा के साथ (10101010)
  • सही स्थानांतरित करें और दाएं-बिट मास्क (01010101)
  • या साथ में परिणाम परिणाम।

स्थानांतरित कर दिया बाईं 01 10 11 00 10101010 के साथ नकाबपोश है हमें 00 10 10 00

देता

स्थानांतरित कर दिया सही (मूल) 01010101 के साथ नकाबपोश है हमें 01 01 00 01

देता है या एक साथ हमारे परिणामों

तो सी या सी ++ आप

unsigned char bitswap(unsigned char uch) 
{ 
    return ((uch<<1) & 0xAA) | (uch>>1) & 0x55); 
} 

बस (सुनिश्चित करें कि आपकी पाश समाप्त हो जाता है!) चलने वाले 0xff को 0x00 से सभी मूल्यों के लिए अपने "तालिका" उत्पन्न करने के लिए कर सकता है में।

+0

स्पष्टीकरण के लिए धन्यवाद! – Chayemor

1

जावा में 32-बिट interger के लिए ..

public int swapOddEvenbits(int x) 
{ 
    return ( ((x & 0xaaaaaaaa) >> 1 | ((x & 0X55555555) << 1)); 

} 

आप 64-बिट के साथ काम कर रहे हैं, तो आप मुखौटा बदलने के लिए की आवश्यकता होगी ..

संबंधित मुद्दे