[C#] Домашно Operators and Expressions - 14 задача


32

 

Задача:
* Write a program that exchanges bits {p, p+1, …, p+k-1) with bits {q, q+1, …, q+k-1} of given 32-bit unsigned integer.
 
Измислих някакво решение, но ще ми е интересно и другите как постъпват към тази задача :)
 
Изпълнявам следните стъпки
 
Питам колко бита ще сменяме: 1,2,3... ?
Питам за позицията на първата група битове за смяна - например 4та
Питам за позицията на втората група за смяна - например 21ва
 
Съответно ако е избрано да се сменят общо поредица от 3 бита ще се сменят:
4,5,6ти с 21,22,23ти бит.
 
Създавам маска със 1ци за съответния брой битове и съответната позиция, които искаме да сменим.
За близката група/4ти,5ти,6ти бит/ битове: 000000...1110000 
За далечната група /21ви,22ри,23ти/ битове: 00000..111000000000000000000000
 
Копирам сегашните стойности на съответните битове в числото в отделни маски с & AND оператор след което измествам битовете съответно в най-дясна позиция.
 
запаметени битове близка група = (Числото & маска–близка-група ) >> изместваме до най-дясна позиция
запаметени битове далечна група = (Числото & маска–далечна-група ) >> изместваме до най-дясна позиция
 
По този начин имаме запаметени съответните битове в най-дясно.
 
След това занулявам /000/ стойностите на съответните битове /4ти,5ти,6ти бит и на 21ви,22ри,23ти бит/ като предварително съм създал маски 
зануляваща маска за близка група - 11111111111111111111111110001111
зануляваща маска за далечна група - 11111111000111111111111111111111
 
След това използвам оператора & AND, за зануля съответните битове и да запазя старите стойности на другите битове.
(Числото & зануляваща маска за близката група)
(Числото & зануляваща маска за далечна група)
 
Измествам запаметените битове до съответната позиция:
 
запаметени битове близка група << до позицията на далечната група
запаметени битове далечна група << до позицията на близката група
 
След което ползвам оператора | OR, за да копирам битовете на съответните позиции:
 
Числото = Числото | (маска-запаметени-битове-близка-група-преместени-на-далечна-позиция)
Числото = Числото | (маска-запаметени-битове-далечна-група-преместени-на-близка-позиция)
 
Please enter how much bits you would like to exchange: 3
Please enter which is the first NEAR bit you'd like to exchange: 4
Please enter which is the first MORE FAR bit you'd like to exchange: 21
The value of the NEAR bit is: 101
The value of the MORE FAR bit is: 101
The mask for the NEAR bit is: 1110000
The mask for the MORE FAR bit is: 111000000000000000000000
Value to be Changed BEFORE transformation:     1010101100100011110011011101
Value to be Changed AFTER set to NEAR BIT:     1010101100100011110010001101
Value to be Changed AFTER se MORE FAR BIT:     1010000100100011110010001101
The Value of (~maskForMoreBit)           : 11111111000111111111111111111111
The Value of (~maskForNearBit)           : 11111111111111111111111110001111
Value to be Changed with ZERO-ED BIT:     1010000100100011110010001101
Value to be Changed with NEAR BIT   :     1010000100100011110011011101
Value to be Changed with FAR  BIT   :     1010101100100011110011011101
00:00:00.0030000
Press any key to continue . . . 
 
 
 
 
 
edit: заглавие на темата и таговете



Отговори



0
И аз самостоятелно започнах да се занимавам и си разглеждам темичките в Ютуб и учебника.. По някакъв начин измислих, как според въведеното число "к" автоматично да се моделира маска чрез низ от стринс и после конвъртТоИнт (пр. 1011; 100011 и т.н.(подобно на 13та, където маск=7(или 111)), а след това операциите са сравнително лесни (като предните задачи)... може и да е мазало, нз :)) -> http://pastebin.com/v5u3h6CE

от tonan8888 (0 точки)


0
Надявам се че работи. Ще посоча само нещата които не ми харесват. Помисли какво да направиш за да ги избегнеш. Първо - това: if ((p == q) || (p == (q+1)) || (p==(q+k-1)) || ((p +1) == q) || ((p+1) == (q+1)) || ((p+1)==(q+k-1)) || ((p+q-1) == q) || ((p+q-1) == (q+1)) || ((p+q-1)==(q+k-1))) просто е ... ужасяващо за разбиране. Предполагам какво би трябвало да прави, но ако има някаква грешка, ще ми трябват 20 минути да разбера кое точно от сравненията се дъни. Вероятно би могъл да направи нещо от типа ... if (p+q > 32) ... не знам просто...
Второ - това: string h = new string('0', (k - 3)); string final = ("1" + h + "11"); int mask1 = Convert.ToInt32(final, 2); int mask2 = Convert.ToInt32(final, 2) за мен е странно... Можеш да направиш така: final = 1; // най-лявата единица я поставям вдясно final = final << k-3; // шифтвам я наляво колкото ми трябва, празните места ще се запълнят с 0 final = final <<2; //правя си място за 2-те единици; final = final + 3; // тройката двоично е "11" и тъй като след шифт-а със сигурност последните два бита са нула, мога да ползвам "+". Сега като погледнеш това дето съм написал, мисля че ще можеш да го оптимизираш лесно. На един ред ще стане: final = (1 << k-1)+3;
Трето: в последния if-else имаш 2 повтарящи се реда, които можеш да ги изкараш след if-a и да се изпълняват винаги. Самия writeline е прието да се пише с placeholder-и - тия {0}, {1} и т.н. Така текста е на едно място а променливите на друго и човек по-лесно чете какво ще се изписва.

от JulianG (5316 точки)

0
Мерси много! Ще се позанимавам още :))

от tonan8888 (0 точки)