Moe Nishinozono écarta ses mains à côté de son visage. Ce n'est pas un geste que l'humanité a adopté le système décimal. (Extrait de "Thirty Little Indians" dans la courte édition d'Hirotsugu Mori "Erasing Madoromi")
L'autre jour, je relisais le livre mystère ci-dessus que j'avais trouvé en organisant la bibliothèque de mes parents, mais j'ai commencé à penser que j'aimerais créer un programme lié à la notation $ n $ parce que c'est un gros problème. .. Donc, cette fois, implémentons l'addition quaternaire en Java comme exemple de notation $ n $. Comme le titre l'indique $ n $, nous visons un codage qui peut être utilisé en notation binaire, quaternaire ou hexadécimale.
Supposons qu'il y ait des gens dans un pays qui calculent toujours en notation quaternaire. Les nombres qu'ils utilisent sont différents des nombres que nous utilisons, et ils semblent ressembler à l'alphabet. Après enquête, j'ai constaté que la correspondance était la suivante.
Peuple quadratique | nous | Quelque chose comme une excuse |
---|---|---|
P | 0 | Arrondi est comme 0 |
I | 1 | Il ressemble à 1 |
T | 2 | Puisque le nombre de coups est de 2, ... |
M | 3 | Faites pivoter 3 de 90 ° vers la gauche et cela ressemble à M |
S'ils écrivent "ITPM", c'est $ 1203_ {(4)} $ dans le nombre décimal que nous utilisons, c'est-à-dire
1203_{(4)} = 1 × 4^3 + 2 × 4^2 + 0 × 4 + 3 × 1 = 64 + 32 + 0 + 3 = 99
Cela signifie que Étant donné deux nombres quaternaires, créez un programme qui génère le résultat de leur ajout en notation quaternaire en utilisant l'alphabet ci-dessus. Par exemple, "I" et "TPM"
1_{(4)} + 203_{(4)} = 1 + 35 = 36 = 210_{(4)}
Par conséquent, il est supposé que "TIP" est émis. Comme je l'ai écrit au début, cette fois, je voudrais l'écrire en notation $ n $, plutôt que de simplement créer un traitement quaternaire.
Comme il est difficile de créer tous les processus de calcul avec des nombres de base $ n $, nous convertirons les deux nombres en nombres décimaux, les calculerons, puis les retournerons en nombres de base $ n $.
Tout d'abord, la valeur de $ n $, qui indique le nombre de base, et le nombre ou caractère utilisé dans chaque chiffre de la base $ n $ (par exemple, en hexadécimal, au lieu de décimal 10, 11, 12, ……, 15 Créez une classe NAryNumber pour stocker A, B, C, ……, F). En outre, un alphabet [A-Za-z] ou un chiffre [0-9] sera attribué à chaque lieu.
class NAryNumber {
private int N; //N valeur de N-aire
private char[] characters; // 0~N-Caractère correspondant à 1
private HashMap<Character, Integer> numbers; // 0~N-Le numéro correspondant à la première lettre
public NAryNumber(int n, char[] c) {
this.N = n;
this.characters = c.clone();
this.numbers = new HashMap<Character, Integer>();
for (int i = 0; i < this.characters.length; i ++) {
numbers.put(this.characters[i], i);
}
}
}
La notation décimale utilise 10 nombres de 0 à 9, mais de même la notation $ n $ utilise $ n $ caractères de 0 à $ n-1 $. La première variable membre N contiendra la valeur de ce $ n $. Les caractères attribués à chaque nombre sont saisis dans les caractères du tableau de type char, mais l'ordre de saisie est toujours le caractère correspondant à 0, le caractère correspondant à 1, le caractère correspondant à 2, etc. Et chaque valeur de 0, 1, 2, …… est stockée dans un type de données appelé tableau associatif au lieu d'un tableau nommé nombres. Cet arrangement associatif est la partie de cet article qui me fait du bien même si je ne le comprends pas bien.
Les tableaux ordinaires sont toujours ordonnés par des nombres entiers supérieurs ou égaux à 0, tels que 0e, 1er et 2e. À ce stade, 0, 1, 2, …… sont appelés __index __ ou __subscript __. D'un autre côté, les tableaux associatifs peuvent utiliser non seulement des entiers mais aussi des chaînes comme index. La chaîne de caractères utilisée pour l'index à ce moment est appelée key (clé).
La raison pour laquelle j'ai décidé d'utiliser un tableau associatif en premier lieu est que, par exemple, lorsque vous essayez de convertir un nombre quaternaire en nombre décimal en utilisant le système quaternaire ci-dessus, les caractères du tableau de type char seuls ne suffisent pas. «T» est là! ⇒ Quel est le nombre du caractère stocké «T»? ⇒ (En vérifiant les valeurs du tableau une par une) Oh, c'est la troisième! ⇒ Alors c'est 2 J'ai pensé que ce serait compliqué d'écrire un peu (même si ce n'est pas impossible). D'un autre côté, si vous utilisez les nombres de tableaux associatifs, vous pouvez faire en sorte que la clé "T" y attache 2, de sorte que vous pouvez obtenir 2 simplement en écrivant numbers.get ("T").
Dans la classe NAryNumber, créez une méthode convFromNAryToDec qui convertit un nombre de base $ n $ donné en un nombre décimal, et une méthode convFromDecToNAry qui convertit un nombre décimal donné en un nombre de base $ n $.
Pour convertir $ n $ base en décimal, vous devez savoir ce qu'est chaque lieu. Par exemple, en notation décimale, la 1ère place est suivie de la 10ème place, de la 100ème place et de la 1000ème place. En notation binaire, la 1ère place est suivie de la 2ème place, de la 4ème place et de la 8ème place. De cette façon, dans le système $ n $, le lieu $ n $, le lieu $ n ^ 2 $ et le lieu $ n ^ 3 $ sont suivis dans l'ordre à partir de la 1ère place, donc multipliez ce nombre par le nombre de chaque lieu. Enfin, si vous en trouvez la somme, vous avez un nombre de base $ n $. Le nombre de chiffres saisis n'étant pas fixe, nous calculerons le nombre de chiffres à partir de la longueur de la chaîne de caractères. C'est pourquoi j'ai décidé d'attribuer un personnage à chaque personne plus tôt.
public int convFromNAryToDec(String nAry) {
int dec = 0; //Valeur obtenue en convertissant un nombre N-aire en nombre décimal
for (int i = 0; i < nAry.length(); i ++) {
//Trouvez la somme dans l'ordre à partir de la 1ère place
dec += numbers.get(nAry.charAt(nAry.length() - 1 - i)) * Math.pow(N, i);
}
return dec;
}
Je convertis de la décimale en $ n $, mais cette fois c'est le contraire, c'est-à-dire diviser au lieu de multiplier. Dans le système $ n $, le chiffre suivant augmente à mesure que le nombre de $ n $ compte, nous voulons donc savoir combien de pièces $ n $ peuvent être regroupées, c'est-à-dire combien de fois elles sont déplacées vers le haut. Cependant, notez que le reste après la division par $ n $ est le nombre de chaque chiffre, mais il est calculé dans l'ordre à partir du chiffre __1 __. En d'autres termes, si vous connectez les restes dans l'ordre dans lequel vous les avez demandés, les réponses seront dans l'ordre inverse. Donc, à la fin, vous devez inverser l'ordre des chaînes.
public String convFromDecToNAry(int dec) {
String nAryRev = "";
//L'ordre dans lequel le reste a été demandé(Ordre inverse)Convertir en N-aire
while (dec >= this.N) {
int rem = dec % this.N;
dec = (dec - rem) / N;
nAryRev += this.characters[rem];
}
nAryRev += this.characters[dec];
//Inversez la chaîne puis retournez
return new StringBuffer(nAryRev).reverse().toString();
}
Enfin, je vais créer la partie d'entrée, mais comme il est difficile de saisir la valeur de $ n $ et les caractères à utiliser pour chaque lieu à partir de la console à chaque fois, j'écrirai la valeur directement dans le programme uniquement cette fois. Pour le moment, nous prévoyons une suite, mais dans ce cas, nous lirons les paramètres écrits dans le fichier texte, alors pardonnez-moi cette fois.
En tant que tel, le programme terminé est le suivant. Dans le réglage quaternaire indiqué au début, la partie d'entrée est écrite pour calculer I + TPM. Le résultat de sortie sera TIP.
import java.util.HashMap;
class NAryNumberTest {
public static void main(String args[]) {
//contribution
int N = 4;
char[] characters = {'P', 'I', 'T', 'M'};
String val1 = "I";
String val2 = "TPM";
//En traitement
NAryNumber nary = new NAryNumber(N, characters);
String result = nary.convFromDecToNAry(
nary.convFromNAryToDec(val1) + nary.convFromNAryToDec(val2)
);
System.out.println(result);
}
}
class NAryNumber {
private int N; //N valeur de N-aire
private char[] characters; // 0~N-Caractère correspondant à 1
private HashMap<Character, Integer> numbers; // 0~N-Le numéro correspondant à la première lettre
public NAryNumber(int n, char[] c) {
this.N = n;
this.characters = c.clone();
this.numbers = new HashMap<Character, Integer>();
for (int i = 0; i < this.characters.length; i ++) {
numbers.put(this.characters[i], i);
}
}
public int convFromNAryToDec(String nAry) {
int dec = 0; //Valeur obtenue en convertissant un nombre N-aire en nombre décimal
for (int i = 0; i < nAry.length(); i ++) {
//Trouvez la somme dans l'ordre à partir de la 1ère place
dec += numbers.get(nAry.charAt(nAry.length() - 1 - i)) * Math.pow(N, i);
}
return dec;
}
public String convFromDecToNAry(int dec) {
String nAryRev = "";
//L'ordre dans lequel le reste a été demandé(Ordre inverse)Convertir en N-aire
while (dec >= this.N) {
int rem = dec % this.N;
dec = (dec - rem) / N;
nAryRev += this.characters[rem];
}
nAryRev += this.characters[dec];
//Inversez la chaîne puis retournez
return new StringBuffer(nAryRev).reverse().toString();
}
}
En passant, si vous réécrivez la partie d'entrée au début comme suit, vous pouvez également calculer en notation hexadécimale. Le résultat de sortie sera FFFFF.
import java.util.HashMap;
class NAryNumberTest {
public static void main(String args[]) {
//contribution
int N = 16;
char[] characters = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
String val1 = "12345";
String val2 = "EDCBA";
//En traitement
NAryNumber nary = new NAryNumber(N, characters);
String result = nary.convFromDecToNAry(
nary.convFromNAryToDec(val1) + nary.convFromNAryToDec(val2)
);
System.out.println(result);
}
}
class NAryNumber {
private int N; //N valeur de N-aire
private char[] characters; // 0~N-Caractère correspondant à 1
private HashMap<Character, Integer> numbers; // 0~N-Le numéro correspondant à la première lettre
public NAryNumber(int n, char[] c) {
this.N = n;
this.characters = c.clone();
this.numbers = new HashMap<Character, Integer>();
for (int i = 0; i < this.characters.length; i ++) {
numbers.put(this.characters[i], i);
}
}
public int convFromNAryToDec(String nAry) {
int dec = 0; //Valeur obtenue en convertissant un nombre N-aire en nombre décimal
for (int i = 0; i < nAry.length(); i ++) {
//Trouvez la somme dans l'ordre à partir de la 1ère place
dec += numbers.get(nAry.charAt(nAry.length() - 1 - i)) * Math.pow(N, i);
}
return dec;
}
public String convFromDecToNAry(int dec) {
String nAryRev = "";
//L'ordre dans lequel le reste a été demandé(Ordre inverse)Convertir en N-aire
while (dec >= this.N) {
int rem = dec % this.N;
dec = (dec - rem) / N;
nAryRev += this.characters[rem];
}
nAryRev += this.characters[dec];
//Inversez la chaîne puis retournez
return new StringBuffer(nAryRev).reverse().toString();
}
}
Cela dit, cette fois, j'ai principalement implémenté la conversion du nombre décimal $ n $ base ⇔. Si possible, je voudrais mettre en œuvre un processus capable de lire les paramètres écrits dans le fichier texte comme décrit ci-dessus et de calculer la formule entrée à partir de la console. Nous travaillerons sur ces questions à l'avenir. Si vous avez une autre chance, veuillez vous entendre avec moi.
Merci pour la lecture.
Ajouté le 13 décembre Dans les commentaires ci-dessous, vous avez souligné l'interface. Vérifie s'il te plaît.
C'est un long aparté, mais pardonnez-moi s'il vous plaît.
Au moment où j'écrivais cet article, je me demandais en quoi consistaient les classes et les encapsulations. Bien sûr, je peux consulter ces explications dans des livres et en ligne, mais quand je me demandais s'il y avait une façon de penser qui me conviendrait, j'ai trouvé un exemple que je pourrais personnellement comprendre. ..
Lorsque vous étiez à l'école primaire ou au collège, vous aviez le rôle d'être membre de l'école. Membres de la classe, membres de la bibliothèque, membres de la santé, etc. Naturellement, il n'y a aucune personne nommée membre du comité XX. La véritable identité est Nantoka Taro, Nantoka Hanako et d'autres personnes qui existent réellement. Alors, pensons que la classe __ fait référence à un rôle __spécifique comme un membre d'un comité de bibliothèque, et que la personne ou la chose qui joue réellement ce rôle __ est une entité (instance) __. Par exemple, Yuki Nantoka, qui lit toujours tranquillement des livres dans la bibliothèque et porte ou ne porte pas de lunettes selon les jours, semble être l'entité d'une classe nommée Comité de la bibliothèque.
Un peu plus délirant, il y a une variable dans la classe du comité de bibliothèque appelée la liste de prêt de livres. Pour des raisons de confidentialité, cette liste n'est pas visible par les personnes non autorisées, ajoutez donc le modificateur private. À la place, ajoutez le modificateur public à la méthode nommée "Afficher la liste de prêt" pour afficher la liste de prêt de livres uniquement à des personnes spéciales telles que les enseignants et les autres membres de la bibliothèque. Ensuite, un processus qui oblige une personne (autre programmeur) qui n'est pas familière avec le travail du comité de la bibliothèque à regarder la liste des prêts par une personne non autorisée (processus qui n'était pas prévu à l'origine ⇒ peut provoquer un bug) Vous pouvez éviter la situation d'écriture (ce sera une erreur si vous l'écrivez). De cette façon, l'une des idées de encapsulation est de rendre inaccessibles les variables et les méthodes (appelées variables membres et méthodes membres) de la classe depuis l'extérieur de la classe et de décider comment s'y référer. Département).
De plus, certains des membres de la bibliothèque sont appelés membres de la bibliothèque __Chief __, qui sont au sommet des membres de la bibliothèque de l'école. Si vous créez une classe appelée Library Committee __Chief __ à partir de zéro, il y aura des inefficacités telles que la copie des variables et des méthodes du comité de bibliothèque (si les spécifications de la liste de prêt de livres changent, le comité de bibliothèque La classe et le comité de la bibliothèque __long__class doivent également être réécrits!). Par conséquent, en créant une classe de comité de bibliothèque __long __ en héritant de la classe de comité de bibliothèque _, les variables et méthodes de la classe de comité de bibliothèque peuvent être utilisées sans avoir à se soucier de les écrire. Il semble que ce n'est pas grave si vous n'ajoutez que le rôle unique à long (comme gérer la présence des membres du comité de bibliothèque).
Enfin, si un rôle est ce qu'est vraiment la classe, il est important de lui donner un nom qui soit facile pour les autres programmeurs de comprendre ce qu'est ce rôle. J'essaie toujours de créer des mots anglais sympas, mais les résultats sont généralement mitigés. La classe NAryNumber cette fois en est également un produit. À propos, conv dans le nom de la méthode est une abréviation de convert, et Dec est une abréviation de Decimal, mais elle n'a aucun sens à moins qu'elle ne soit transmise. Veuillez noter qu'une telle dénomination n'est pas très bonne.
Merci d'avoir lu dans un tel endroit.
Recommended Posts