Loading...
ViValDam avatar ViValDam 15 Точки

[Homework] C# Basics - Operators Expressions and Statements - Problem 16** Exchange Bits (Advanced)

overloadСпоред мен третият пример в задачата е грешен - при него се получава type overload, имаме 32 битов , unsigneg integer , което означава 32 бита в позиции от 0 до 31  , а при този пример се получават от q+k = 22 + 10 = 32 позиция(такава няма!), което би трябвало да хвърли ексепшън - и на мен ми хвърля !

Но в отговора е даден нормален резултат...

Вашето мнение ? Къде бъркам ? Ако бъркам ?

Иначе ,задачата си я реших , с побитови операции, имам и оверлапинга и всички ексепшъни и всички останали стойностти ми излизат с правилни отговори - гектвах даже и тези от 15 задача,  с к = 3 - всичко правилно. Всъщност 15 задача е частен случай на 16.

На мен са ми лесни операциите с битове - ако иска някой да пита - ще помагам !

Edited: Променено e името на темата и са добавени подходящи тагове.

2
Programming Basics 18/11/2014 21:44:13
tosilv avatar tosilv 69 Точки

{q, q+1, …, q+k-1} е условието.

q+k-1 = 22+10-1 = 31

 

0
ViValDam avatar ViValDam 15 Точки

Да знам , аз съм го сложила в цикъла от 0 до К-1 се въртят позициите .

Това к-1 е заради номерацията на битовете, тя е от 0 до 31 , а не от 1 до 32, от там идва и к-1, иначе са си все 32 бита , ще видя условието ми в ексепшъна за оверлод , ще пробвам да го променя .

На теб излиза ли този пример ?

 

 

1
tosilv avatar tosilv 69 Точки

Ако смяташ по условието на задачата не стигаш до 32 позиция(стигаш до 31), така че предполагам че сметките са грешни.

 

Ако се омотаеш пусни код да го видим. 

0
ViValDam avatar ViValDam 15 Точки

Практически имаме само 3 операции с битове .

1.Първата е откриването на стойността на бит, по дадена негова позиция( дали стойността в бита  е 0 или е 1 ).

2.Втората е инсталиране на стойност 0 в бит с дадена позиция (независимо то това , какво има в него, все едно дали има в него  0 или 1).

3.Третата е  инсталиране на стойност 1 в бит с дадена позиция (независимо то това , какво има в него, все едно дали в него има  0 или 1) .

И това е всичко .

Като знаем формулките за всяка една от тези операции сме готови, за всякакви задачи с битове .

На мен ми се видяхя много лесни, може би защото очахвах, по чуждите мнения, да са ужасно трудни - но не са - така ,че не се страхувайте от този тип задачи.

Ето един линк ,за побитови операции , на един WORKSHOP от академията Телерик, може да се окаже полезен на някого:

 http://www.youtube.com/watch?v=8vxQqbFGW-E

 

 

2
RoYaL avatar RoYaL Trainer 6849 Точки

О, по повод последния отговор - писал съм главно РНР преди това и един път не ми се е налагало да използвам битовете като различно от стрингова резпрезентация, и не беше толкова лесно да вникна в баш побитовите операции :))

Иначе, да, в тези задачи се извършва точно това - намира се бит на определеня позиция и на него се слага 1 или 0.

За мен обаче е доста по клийн, ако двата бита (от който ще заменяш, и когото ще заменяш) са еднакви - просто да не правиш нищо. Да заменяш 0 с 0 или 1 с 1 ми се струва безсмислено.

https://github.com/RoYaLBG/SoftUni/blob/master/OperatorsExpressionsStatements/BitwiseInteraction/AdvancedBitExchange.cs

Ето някакво що-годе клийн решение.

Не е много красив кода, ще го дооправя, за сега си експериментирам разни други неща пр. да се пуска всеки скрипт от солюшъна от едно място, в зависимост от юзър инпут-а (за това метода ми тук е Start(), а не Main()) така че не обръщайте внимание на това.

 

0
ViValDam avatar ViValDam 15 Точки

  

Аз също мислех отначало , да правя проверка , за това дали са еднакви и ако са еднакви да не прави нищо програмата , но става по-дълго така и повече операции се извършват , отколкото да се вкарва 1 или 0, даже и да са еднакви.

Ето ми го кода - работи си нормално с всички стойностти и дава същите резултати ,като показаните ,освен в споменатият по-горе пример, който според мен оверфлоува 32- та бита на лонг интежер.

Като вдигна с 1 битовете , пък дава друг резултат от този в примера , подобен но друг.

Mod Edit: Нарушена т. 12 от Правилата на форума: Във всеки пост е позволено цитирането на не повече от 15 реда код. Ако искате да споделите по-дълъг код, използвайте сайтове като Pastebin и Github Gist).

 

 

 

1
10/11/2014 16:38:42
RoYaL avatar RoYaL Trainer 6849 Точки

Ауч, моля те, качи го някъде :)

Иначе, кодът, който аз дадох, работи с всичките примери, освен тези които де факто според задачата overlap-ват или са out of range

0
ViValDam avatar ViValDam 15 Точки

моят работи и с оверлод и с оверлап

 

Вижуал студио ще ти го прочете и така - неформатиран. Нямам време да го качавам на други места.

 

Ти ползваш неща , които не сме учили - аз само такива ,които сме учили , освен цикли, които още не сме , но ни казаха да си прочетем и да ползваме .

Отвори един нов файл , изтрий всичко и копирай моя код, ще тръгне и не форматиран - ако искаш да видиш моята програма.

1
RoYaL avatar RoYaL Trainer 6849 Точки

Не го чете заради коментарите.

Като имаш

// comment

(new line)

int x = 1;

 

и се слеят на един ред, int x = 1 се закоментирва, така че не мога да го компилирам.

0
ViValDam avatar ViValDam 15 Точки

Оправих го горе, вече може да го пуснеш !

Малко още е изкривено, но тава вече може сам са си го оправиш .smile

1
RoYaL avatar RoYaL Trainer 6849 Точки

Макс value-то за K е 32-x, а не 31-х. Т.е. в третия пример е съвсем валидно да имаш q=22; k=10 и общ сбор 32

0
ViValDam avatar ViValDam 15 Точки

Пак дава грешна стойност - пробвала съм !

А на всички останали - правилни , даже и тези стойностти  от 15 задача пробвах, за  p=3, q=24 , k =3 - всичките излизат правилно.

Ей сега го пуснах това число и в задача 15  със стойности  2, 22 и к =10  в цикъла и пак дава друг резултат , ето този , същият резултат , като от алгоритъма от 16 !

1907749073  дава и този е верният отговор !

100% съм сигурна ,че е грешен отговора в примерите  !

Просто не може алгоритъма да е грешен, като всички останали са правилни , освен този !

А това с к = 32 , съм съгласна, аз дълго време се чудех, кое ще е 31 или 32 и така е 32  е броя на всички битове на uint , 32 e k  и  гопоправих ,но то не дава отражение на отговора , а само но овърфлоуто с едно число повече става така и така е правилно.

 

Но отговора на пример 3 е грешен - не знам, как на теб ти излиза !

 

 

 

 

0
TodorovH avatar TodorovH 216 Точки

ViValDam броиш ги неправилно и ги събираш неправилно!!!

Айде да ги броим заедно:

 

к 1  заменя се 22 бит с 2-рия

к 2  заменя се 23 бит с 3-тия

к 3  заменя се 24 бит с 4-тия

к 4  заменя се 25 бит с 5-тия

к 5  заменя се 26 бит с 6-тия

к 6  заменя се 27 бит с 7-мия

к 7  заменя се 28 бит с 8-мия

к 8  заменя се 29 бит с 9-тия

к 9  заменя се 30 бит с 10-тия

к 10 заменя се 31 бит с 11-тия

Като гледам всичко си е ок!!! Ти как мислиш??? cool

1
hristolilov avatar hristolilov 394 Точки

Ето и моето решение, след 2 часа родилни мъки се плеснах по челото и зацепих, че с една елементарна промяна на маската от предишната задача и набутването на кода 1 към 1 в for loop, нещата стават бетон...

staticvoid Main()

{

Console.Write("Enter number: ");

long number = uint.Parse(Console.ReadLine());

Console.Write("Enter p: ");

int p = int.Parse(Console.ReadLine());

Console.Write("Enter q: ");

int q = int.Parse(Console.ReadLine());

Console.Write("Enter k: ");

int k = int.Parse(Console.ReadLine());

if (Math.Max(p, q) + k > 32)

{

Console.WriteLine("Out of range");

}

elseif (Math.Min(p, q) + k > Math.Max(p, q))

{

Console.WriteLine("Overlapping");

}

else

{

int counter = q;

for (int i = p;i<=p+k-1;i++)

{

//Prosto kodut ot predishnata zadacha, vkaran v for cikul i s druga maska.

long mask = 1;

long firstBits = ((mask << i) & number) >> i;//Get bit p

long secondBits = ((mask << counter) & number) >> counter;//Get bit q

number = number & ~(mask << i);//Convert bit p to 0

number = number & ~(mask << counter);//Convert bit q to 0

number = number | (secondBits << i);//Replace bit p with q

number = number | (firstBits << counter);//Replace bit q with p

counter++;

}

Console.WriteLine(number);

Console.WriteLine(Convert.ToString(number, 2).PadLeft(32,'0'));

}

}

За сравнение, ето как съм решил предишната:

staticvoid Main()

{

Console.Write("Please eneter a number: ");

long number = uint.Parse(Console.ReadLine());

Console.WriteLine("You entered the number {0} in binary: {1}", number, Convert.ToString(number, 2).PadLeft(32, '0'));

long mask = 7;

long firstBits = ((mask << 3) & number)>>3;//Get bits 3,4,5

long secondBits = ((mask << 24) & number)>>24;//Get bits 24,25,26

number = number & ~(mask << 3);//Convert bits 3,4,5 to 0;

number = number & ~(mask << 24);//Convert bits 24,25,26 to 0;

number = number | (secondBits << 3);//Replaces bits 3,4,5 with saved bits 24,25,26

number = number | (firstBits << 24);//Replaces bits 24,25,26 with saved bits 3,4,5

Console.WriteLine("Result is: {0}",number);

Console.WriteLine("In binary: {0}",Convert.ToString(number, 2).PadLeft(32, '0'));

}

 Всичко на всичко, без форматирането, инпута и проверките - 9 реда код.Вече мога да спя спокойно :D

7
ViValDam avatar ViValDam 15 Точки

Променливите в тази задача трябва да бъдат uint - изрично е посочено в условието !

С long, разбира се задачата става чудесно , понеже е по висшият тип на интежер, но задачата е с  uint и

точно от там на мен ми се получаваше грешката , която с long няма как да се получи !!!или по точно орязването на последният бит - виж кода ми по-горе- битовете са декларирани в int, което дава орязването на последният бит при променливите без знак , каквито са тези от тип  uint   !

int bitPValue;

int bitQValue;

и това орязва последният бит на  uint, който в  uint е число , а в  int езапазен за знака !

Като ги смених с 

uint bitPValue;

uint bitQValue;

и примера  , който не ми излизаше  и който стига точно до този бит със знака в интежер, ми излезе .

 

Иначе и моят код е кратък, това отпред са хващане на ексепшъни с try parse, които си упражнявах в моментаsmile

 

Ето го -без коментари и хващане на ексепшъни , и без хващане на оверлап и оверфлоу:

uint bitPValue;

uint bitQValue;

uint maskP;

uint maskQ;

for (int i = 0; i <= k-1; i++)

{

    maskP = 1u << p;

    bitPValue = (int)(number & maskP) >> p; 

    maskQ = 1u << q;

    bitQValue = (int)(number & maskQ) >> q; 

    if (bitPValue == 1) 

   {

         number = number | maskQ;

   }

   else 

   {

         number = number & maskQ;

   }

   if (bitQValue == 1) 

   {

          number = number | maskP ;

   }

   else 

   {

          maskP = ~ maskP;

          number = number & maskP;

   }

   p ++;

   q ++;

   } 

   Console.WriteLine("\nResult : \n\n" + number + " \n\n\n");

}

 

, но оверлап и оверфлоу също са дадени да бъдат хванати в задачата !

 

 

1
ivaylo.yanchev.5 avatar ivaylo.yanchev.5 80 Точки

Досега писах задачата. Имам съмнение, че има невярни примери:

123456789
26
0
7
-
-
out of range

Това при мен си се изчислява, защото p + k - 1 (в случая 32) не е по-голямо от 32. При мен дава резултат: 1465634113.

Това пък:

33333333333
-1
0
33
-
-
out of range

направо гърми, защото е препълнен uint (то се вижда де - uint е макс 10 цифри). :)

 

//Write a program that exchanges bits {p, p+1, …, p+k-1} with bits {q, q+1, …, q+k-1} of a given 32-bit unsigned integer.
//The first and the second sequence of bits may not overlap.

using System;

class BitExchangeAdvanced
{
  static void Main()
  {
    uint myNumber; //n
    uint movedNumber; //the result
    int initialFirstBitRow; //p
    int initialSecondBitRow; //q
    int bitCounter; //k

    do
    {
      Console.WriteLine("Please enter a positive integer:");
      myNumber = uint.Parse(Console.ReadLine());
    }
    while (myNumber < 0);
    Console.WriteLine("Please enter the initial bit in the First row (p):");
    initialFirstBitRow = int.Parse(Console.ReadLine());
    Console.WriteLine("Please enter the initial bit in the Second row (q):");
    initialSecondBitRow = int.Parse(Console.ReadLine());
    Console.WriteLine("Please enter the number of bits in each row (k):");
    bitCounter = int.Parse(Console.ReadLine());

    //initial validation
    if (initialFirstBitRow < 0 || initialFirstBitRow > 31 || initialSecondBitRow < 0 || initialSecondBitRow > 31 || bitCounter < 1 || bitCounter > 32)
    {
      Console.WriteLine("Out of Range");
      return; //exit the program
    }

    if ((initialFirstBitRow + bitCounter - 1) > 31 || (initialSecondBitRow + bitCounter - 1) > 31)
    {
      Console.WriteLine("Out of Range");
      return; //exit the program
    }
    if (initialFirstBitRow == initialSecondBitRow)
    {
      Console.WriteLine("Overlapping");
      return; //exit the program
    }
    if (initialFirstBitRow < initialSecondBitRow)
    {
      if ((initialFirstBitRow + bitCounter -1) >= initialSecondBitRow)
      {
        Console.WriteLine("Overlapping");
        return; //exit the program
      }
    }
    if (initialFirstBitRow > initialSecondBitRow)
    {
      if ((initialSecondBitRow + bitCounter - 1) >= initialFirstBitRow)
      {
        Console.WriteLine("Overlapping");
         return; //exit the program
      }
    }

    movedNumber = myNumber;

    for (int i = initialFirstBitRow; i <= initialFirstBitRow + bitCounter - 1; i++) //replace first bit row
    {
      movedNumber = ModifyBitAtGivenPosition(movedNumber, i, GetBitAtGivenPosition(myNumber, initialSecondBitRow + (i - initialFirstBitRow)));
    }

    for (int i = initialSecondBitRow; i <= initialSecondBitRow + bitCounter - 1; i++) //replace second bit row
    {
      movedNumber = ModifyBitAtGivenPosition(movedNumber, i, GetBitAtGivenPosition(myNumber, initialFirstBitRow + (i - initialSecondBitRow)));
    }

    Console.Write("The binary representation of the number is: ");
    Console.WriteLine(Convert.ToString(myNumber, 2).PadLeft(32, '0'));
    Console.Write("The binary representation of the moved number is: ");
    Console.WriteLine(Convert.ToString(movedNumber, 2).PadLeft(32, '0'));
    Console.WriteLine("The decimal representation of the moved number is: {0}", movedNumber);
  }

  //this function gets the bit at bitIndex in myNumber integer
  static uint GetBitAtGivenPosition(uint myNumber, int bitIndex)
  {
  return ((myNumber >> bitIndex) & 1);
  }

  //this function changes the bit at bitIndex to bitValue in the myNumber integer
  static uint ModifyBitAtGivenPosition(uint myNumber, int bitIndex, uint bitValue)
  {
  return (bitValue == 0) ? myNumber & (uint)(~(1 << bitIndex)) : myNumber | (uint)(1 << bitIndex);
  }
}

 

Едит: Май видях къде бъркам - в 32-битовите числа мога да сменям от бит 0 до бит 31

0
ViValDam avatar ViValDam 15 Точки

Ивайло, сложи  абсолютно всичките си променливи в  uint - виж мойте коментари горе защо - и аз получавах същата "грешка" !   uint е без знак и ползва 32 бит за стойностти, докато  int , който има числа с + и числа с - , ползва 32 бит за знака - от там идва грешката !

1
ivaylo.yanchev.5 avatar ivaylo.yanchev.5 80 Точки

Минаването от int към uint ми създаде известни ядове, но е направено умишлено - в примерите има вариант p и q да са отрицателни. Благодаря за съветите, прегледах коментарите!

0
orlinov avatar orlinov 11 Точки

Ето и моето решение. Проверявам дали k плюс по голямото от p и q  е по голямо от 32 или дали p или q  е по-малко от нула. В този случай сме извън рейнджа. Ако абсолютната стойност от q-p е по-малка от к имаме овърлапинг

2
FunnyBunny avatar FunnyBunny 38 Точки

Здравейте, ако може някой да погледне моето решение на задачата тук. Заиграх се с типовете променливи. В началото зададох int, после като тествах, не ми стигна - замених го с uint и най-накрая с long. Във VS ми се появиха някакви грешки, но без описание. Имаше и предупреждения преди крайния вариант, но не разбрах какво не му харесва. Благодаря!

0
Filkolev avatar Filkolev 4482 Точки

Visual Studio те предупреждава, че ползваш битова операция между два различни типа данни. Ако не внимаваш това може да доведе до грешки. Не значи, че нещо не е наред, но ако програмата ти дава грешен отговор първо се насочи към тази част от кода и виж дали там не се получава проблем.

По принцип за предпочитане е да ползваш еднакви типове, т.е. направи си една единица от тип long и няма да ти го показва това предупреждение.

1
FunnyBunny avatar FunnyBunny 38 Точки

В момента е така:

long mask1 = 1;
mask1 = mask1 << i;
firstResult = (mask1 & number) >> i;

Дали не му харесва, че i позицията е int?

 

Edit: Въщност затворих и отворих наново проекта и грешките изчезнаха. Може би не е могло да се refresh-не. Благодаря smile

0
18/11/2014 19:06:53
Filkolev avatar Filkolev 4482 Точки

Не си декларирал/а правилно маските като long, трябва да им сложиш суфикс, напр. long mask1 = 1L;

1
18/11/2014 19:06:32
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.