web-dev-qa-db-fra.com

Programmation: étapes minimales requises pour convertir un nombre binaire à zéro

Je travaillais sur un exercice de programmation et je suis resté coincé à déterminer l'algorithme correct. Voici le problème:

Compte tenu d'un nombre décimal, combien d'étapes minimales possibles sont nécessaires pour convertir ceci en zéro fourni:

  1. Changer le bit i si le bit suivant i + 1 est '1' et tous les autres bits i + 2 et plus tard sont 0
  2. Changer le dernier bit sans restriction

Par exemple:

si l'entrée est (8) base10 = (1000) base2, les étapes prises sont les suivantes:

1000→1001→1011→1010→1110→1111→1101→1100→0100→0101→0111→0110→0010→0011→0001→0000

total 15 étapes sont nécessaires.

Complétez la définition suivante:

int minStepsRequired(long number)

Il est correct d'obtenir un pseudo code ou juste l'algorithme. Ce n'est pas un devoir ou une mission.

14
roger_that

Il est important de noter que les premiers k bits, qui sont des zéros peuvent être laissés à leur guise et que vous ne commencez que par le (k + 1) 'ème bit et nous ignorons tous les bits de départ, ayant une valeur de zéro et toujours visible augmenter leur nombre. C'est notre objectif principal et nous réduisons donc toujours l'espace de problème à un espace similaire, mais plus petit. Maintenant, en supposant que votre numéro ressemble à

1 b1b2b3 ... bn

vous devez vous assurer que B1 est 1 et B2, B3, ..., Bn est 0 afin de pouvoir modifier le bit avant B1 à 0. Après cela se produisait, vous savez que B2 est 1 et tous les suivants Les bits sont 0, puis le nouvel objectif est de changer B2 à 0, sachant que tous les bits suivants sont 0.

Vous pouvez garder une trace de vos progrès avec une pile qui peut avoir autant d'éléments que de nombreux bits que vous travaillez, toujours son sommet représentera votre objectif actuel.

Ainsi, lorsque vous souhaitez zéro votre premier bit, la réussite de la bonne séquence de bits suivants représente des sous-tâches pour vous avant de pouvoir changer votre bit et une fois que vous avez réussi à faire, vous devez procéder de la même manière, mais ignorez le premier bit. Vous pouvez numéroter les étapes.

En supposant qu'un certain nombre de

1 ... 0000000

peut être mis à zéro dans 2 ^ n-1 étapes, le nombre total d'étapes à faire correspondre à 2 ^ n-1 + le nombre d'étapes nécessaires pour atteindre la combinaison que nous voyons ci-dessus. Je n'ai pas vérifié s'il est 2 ^ n - 1 cependant

2
Lajos Arpad

Voici un PHP Mise en œuvre de l'algorithme "FAST WAY" de OLE ". L'idée est la même:

  • Initialiser le résultat avec le premier bit du nombre (à partir de la gauche)
  • Pour chaque bit suivant du numéro, XOR IT avec le bit précédent du résultat, ce qui donne un nouveau bit pour le résultat
function getBit($number, $i)
{
    // Extracts bit i from number
    return ($number & (1<<$i)) == 0 ? 0 : 1;
}

function minStepsRequired($number)
{
    $i = 30; // Enough to handle all positive 32-bit integers
    $bit = getBit($number, $i); // First bit
    $res = $bit;
    do
    {
        $i--;
        $bit ^= getBit($number, $i); // Computes XOR between previous bit of the result and current bit of the number
        $res = ($res<<1) + $bit; // Shifts the result to the left by 1 position and adds the new bit
    }
    while($i>0);
    return $res;
}

var_dump(minStepsRequired(8)); // Outputs 15
var_dump(minStepsRequired(115)); // Outputs 93
2
Olivier

Au début, j'ai essayé de le résoudre avec une fonction de profondeur récursive - première (en nœuds), mais cela vient de travailler pour de petits nombres - une valeur d'entrée telle que 10^5 générerait une erreur d'exécution en raison du nombre d'appels récursifs dans la pile.

Alors j'ai essayé de voir comment je pourrais réduire le problème à la somme des problèmes plus petits et découvert que le nombre d'étapes pour n, étant une puissance de 2, était

Règle 1

N * 2 - 1

(E.G.: Nombre d'étapes pour 2 est 3, car 32 est 63, pour 256 est 511, etc.).

Ensuite, j'avais trouvé quoi faire avec n'importe quel autre nombre (ce n'est pas une puissance de 2) et, puisque tout entier est la somme de différents pouvoirs de 2 (d'où la représentation binaire), je n'ai eu qu'à voir si le nombre d'étapes serait Ajoutez-vous aussi ... mais ce n'était pas le cas. Cependant, j'ai trouvé que je devais simplement ajouter le nombre de pas de chaque pouvoir de deux, mais à

Règle n ° 2

soustrayez et ajoutez les étapes d'une autre mode, à partir du chiffre de commande le plus élevé.

Manifestation

Nombre donné 42 (101010 en binaire)

Appliquons d'abord règle n ° 1

1 0 1 0 1 0
^ ^ ^ ^ ^ ^
| | | | | |_           0 steps
| | | | |___  2*2-1 =  3 steps
| | | |_____           0 steps
| | |_______  2*8-1 = 15 steps
| |_________           0 steps
|___________ 2*32-1 = 63 steps

Et deuxièmement, appliquer règle n ° 2:

63 - 15 + 3 = 51

Le nombre total d'étapes est 51

1
nicolasdij