CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[Java] Petit problèmes avec les listes chaînées

Vexallus
Vexallus
Niveau 10
31 décembre 2014 à 05:39:11

Je fais des listes chaînées avec des class en fait (exercice, je sais qu'il existe un import pour ça) :

:d) Ma class list :

import java.util.Scanner;

public class Liste {
  private int valeur;
  private Liste suivant;

  public Liste(int premier, Liste reste){
    this.valeur = premier;
    this.suivant = reste;
  }

  public int taille(){
    int n = 0;
    Liste p = this;
    while (p != null){
      n++;
      p = p.queue();
    }
    return n;
  }

  public boolean contient(int x){
    Liste p = this;
    while (p != null){
      if (p.tete() == x) return true;
      p = p.queue();
    }
    return false;
  }

  public int tete(){
    return this.valeur;
  }

  public Liste queue(){
    return this.suivant;
  }
  /*public int val(){
    return this.valeur;
  }*/
}

:d) MON MAIN :

import java.util.Scanner;

 
public class prog {
 
  public static void main(String[] args) {
  	Liste s;
  	s.tete = 12;




  	System.out.println("La tete vaut" + s.tete);
  }
}

J'ai 2 errors assez étranges : https://image.noelshack.com/fichiers/2014/01/1420000683-java.png

Bunyan
Bunyan
Niveau 17
31 décembre 2014 à 11:52:30

    Liste s;
    s.tete = 12;

Te provoquera une NPE. Ta variable "s" n'est pas initialisée.

s.tete = 12

indique que tu mets "12" dans l'attribut "tete" de l'objet "s" de type "Liste". En lisant ton objet "Liste", "tete" est une méthode, donc on invocation est ainsi :

s.tete();

La méthode "tete" est un un accesseur, un getter. Elle ne sert qu'à retourner une valeur, rien d'autre.
Vouloir attribuer 12 à "tete" revient à vouloir attribuer 12 à "valeur" suivant ton code. Ainsi, il faudrait plutôt faire :

Liste s = new Liste(12, null);

Je te conseil de revoir ça a tête reposée, car il y a des bases que tu ne comprends pas encore très bien :
- accesseur
- passage d'argument
- affectation
- initialisation d'objets

Vexallus
Vexallus
Niveau 10
31 décembre 2014 à 18:48:36

c'est bon j'ai revu tout ça en fait maintenant le problème c'est pour lier ma class Liste à la class "prog" où j'ai mis mon main

on m'a dit qu'il fallait l'instancier,c'est ça ?

Vexallus
Vexallus
Niveau 10
31 décembre 2014 à 19:07:17

ah j'ai essayé ça :
j'ai écrit

"package lis;" tout en haut de Liste.java (public class Liste)

et j'ai mis "import lis.Liste;" au début du fichier où j'ai mis mon main
ça va ?

du coup j'ai cette erreur :
https://image.noelshack.com/fichiers/2014/01/1420049226-j.png

Vexallus
Vexallus
Niveau 10
31 décembre 2014 à 19:59:32

ah c'est bon j'ai actualisé tout ça regardez :

MAIN:

import Liste;

public class prog {
 
  public static void main(String[] args) {
  	Liste s = new Liste(5, null); //instanciation d'un objet de la classe Liste
  	//s.valeur = 12;




  	System.out.println("La tete vaut" + s.tete());
  }
}

Là je crois que je suis censé importer ma class java Liste dans mon main
Mais genre on m'a dit de les mettre dans le même dossier et de faire

"import nomClasse;"

Mais le problème c'est que j'ai une erreur :
https://image.noelshack.com/fichiers/2014/01/1420052347-j.png
On dirait qu'il la reconnaît pas :( (j'utilise la bonne méthode ou pas ?)

on m'a parlé d'instancier ma classe mais je crois que c'était parce que j'avais pas mis de "new" etc pour la classe Liste

Message édité le 31 décembre 2014 à 20:00:10 par Vexallus
BeatHazard
BeatHazard
Niveau 9
01 janvier 2015 à 01:18:18

C'est important d'avoir un projet bien organisé. Les packages sont utiles pour regrouper des classes et définir une hiérarchie dans un projet (package est un dossier). Import va permettre à ta classe d'utiliser une ou plusieurs classes d'un autre package.

Un exemple simple :
\com\monapplication\mesclasses : va contenir tes fichiers de classes, il faut ensuite définir dans ces classes le package où elles situent avec :
package com.monapplication.mesclasses;

\com\monapplication : va contenir une classe de test. De la même façon il faut déclarer son package :
package com.monapplication;
Maintenant si tu veux utiliser des objets qui sont instanciés par les classes que tu as créées, il faut utiliser import :
import com.monapplication.mesclasses.*; \\Pour import toutes les classes du package.
ou
import com.monapplication.mesclasses.nomdelaclasse;\\Pour importer seulement une classe.

Voila en espérant que cela t'aide.

Vexallus
Vexallus
Niveau 10
01 janvier 2015 à 02:13:01

oulà euh mais j'ai que ces deux classes moi

ça fait quoi du coup ?
c'est un simple projet pour créer une calculatrice !

ryviel
ryviel
Niveau 5
01 janvier 2015 à 02:51:08

En bref, les packages sont comme des chemins de dossiers sous Windows, Linux, Mac etc ..., ou encore comme une URL.

Si tes deux classes sont dans le même dossier, tu n'as pas besoin de faire import.
Si ce n'est pas le cas, alors tu dois faire un import.
Et tu ne peux pas faire d'import si ta classe se trouve dans le package par défaut (le dossier src par exemple).

Vexallus
Vexallus
Niveau 10
01 janvier 2015 à 08:09:01

ahh j'ai pas besoin de faire d'import si c'est dans le même dossier ? :ouch: ah d'acc' merci !

c'est bon le programme marche :ouch: (en fait c'était les bug d'avant qui faisaient une erreur quand je lançait le programme :ouch:)

Merci :ouch2: :bave:

Vexallus
Vexallus
Niveau 10
01 janvier 2015 à 09:14:04

ah et le truc que je voulais savoir c'est que je comprends pas comment je passe à la valeur suivante vu que "this.suivant" est une valeur private ?

je peux le faire avec une des fonctions de ma class Liste ? (c'est ce qu'on a copié en cours mais j'ai pas tout compris)

Vexallus
Vexallus
Niveau 10
01 janvier 2015 à 10:44:57

J'ai créé une classe pour rentrer une valeur à l'endroit où on se trouve parce que ce que j'avais là me permettait pas de le faire j'imagine ?

 public Liste inser(int v){
    this.valeur = v;
    return this.suivant;
  }
Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 01:23:25

Mise à jour :

en fait je dois coder une calculatrice qui peut prendre des int de taille infini (sans utiliser "BigInteger")

donc comment je pourrais faire pour que l'utilisateur ait juste à taper son chiffre puis ensuite je peux le "découper" de manière à mettre chaque chiffre dans une liste ? :(

J'ai pensé à ptêt' les mettre dans un tableau ?

après y'a une solution qui va forcément marcher mais qui sera chiante c'est une boucle où :
l'utilisateur tape un entier, il appuie sur "entrée"
cet entier est stocké dans this.valeur
puis on passe à l'élement suivant et on relance la boucle jusqu'à ce que l'utilsateur tape "eof" pour indiquer qu'il a fini de taper son nombre ? :(

Message édité le 02 janvier 2015 à 01:25:20 par Vexallus
ryviel
ryviel
Niveau 5
02 janvier 2015 à 02:06:50

Je pense déjà que le concept de la liste chainée t'échappe.

Le principe est d'avoir des cellules qui contiennent des valeurs. Ces cellules sont reliées entre-elles par un attribut de classe qui garde une référence sur une autre cellule (la suivante dans le cas d'une liste chainée simple). Dans ce cas, tu te retrouves juste avec une cellule possédant une valeur, et qui "connait" la cellule suivante. Si aucune cellule ne se trouve après, alors la référence est null.

La Liste serait juste le moyen de cacher tout cela à l'utilisateur (même si au final, tu es l'utilisateur). La classe Liste possèderait donc elle aussi un attribut de type Cellule, qui se nomme la tête. Si la tête est null, alors la liste est vide.
Par contre, si l'on souhaite ajouter un nouvel élément, c'est la classe Liste qui s'en charge ! Et non pas les cellules ! Il suffira donc de parcourir les cellules une à une à partir de la tête, jusqu'à ce que tu tombes sur celle qui n'a pas de suivante.
Dès que cette cellule est trouvée, tu créé une nouvelle cellule qui contient la valeur à insérer et qui n'a pas de cellule suivante (null). Cette cellule créée sera maintenant la "suivante" de la cellule "trouvée" (celle qui n'avait pas de suivante).

Après, peu importe comment tu appelles "Cellule" et "Liste", il serait même possible de combiner les deux (comme ce que tu as fait), et d'autres personnes pourraient te donner une modélisation complètement différente.

En tout cas, je ne sais pas du tout où tu en es dans ton programme, mais je vais me basé sur les éléments en ma possession:

  • Soit tu continues avec ta classe Liste, et dans ce cas, il faut que tu gère correctement ton insertion de nouvel élément (avec ce que je viens de dire avec Cellule et Liste qui reste en un sens, toujours vrai).
  • Soit tu peux essayer de faire petit à petit ce que j'ai pu donner comme explications plus haut.

En ce qui concerne la calculatrice :
Si tu demandes à l'utilisateur de taper un nombre très grand et de le récupérer sous forme de String, tu pourras découper ton nombre comme tu le souhaites (donc chiffre par chiffre d'après ce que j'ai cru comprendre). En très bref (et sans vouloir mâcher trop le travail) :

  • chaine.charAt(...); pour récupérer le n-ième caractère de la chaine
  • Character.getNumericValue(...); (c'est une méthode statique) pour transformer ton caractère en entier

Après, je me demande bien comment tu vas faire pour gérer les retenues des opérations avec ce système de liste... (faisable mais c'est une torture pour mon esprit, surtout à une heure si tardive)

PS: Il se peut aussi que je soit complètement à côté de la plaque vu l'heure ...

Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 03:58:32

", il faut que tu gère correctement ton insertion de nouvel élément"

Elle est mal gérée là ? :( j'ai le truc qui fait qu'on peut passer à la cellule suivant etc hein y'a pas de soucis pour ça

oui après j'vais rajouter une fonction "estVide()" pour tester si la liste est vide mais par exemple : comment je reviens à la tête de ma liste ? (vu qu'on avance on avance mais après ? je suis obligé de faire une liste doublement chaînée ? ça va être assez compliqué ptêt' ?)

puisque ce que tu appelle "cellule" c'est la tête, alorsj e l'ai déjà non ? :( (regarde mon code en haut)
je suis censé utilisé que les listes je crois d'ailleurs :( )

merci pour les fonctions ! :oui: j'vais vérifierqu'on ait le droit de les utiliser mais je pense que oui

merci ! :ok:
(pour les retenues j'vais fair un truc du style "if resultat > 10)" et là on rentre dans une boucle qui va le décrémenter jusqu'à ce que ça arrive à 9 pour compter la valeur que prendra la retenue, et après je ferais un "if (retenue)" -> là je la rajoute au calcul d'après, et après je fais retenue = NULL; pour pas que ça mette ma retenue partout)

mai merci de m'y faire penser :oui:

Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 05:42:23

j'y pense maintenant : un string il a une limite de caractère aussi nan ? :(

donc on pourra pas mettre des trucs de taille infinie au final ? :(

Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 07:00:28

Mise à jour : j'ai essayé qq trucs, voici mon code :

http://pastebin.com/8C2aUeWA

ça compile mais quand je rentre un entier j'ai cette erreur :
https://image.noelshack.com/fichiers/2015/01/1420178393-j.png étrange :(

Merci de ton aide en tout cas :oui:

ryviel
ryviel
Niveau 5
02 janvier 2015 à 15:07:12

Étant donné que l'on a pas tout ton code, voici une implémentation personnelle avec les explications que j'ai pu donner dans mon dernier message :

  • Liste.java : http://pastebin.com/XviDZ0k5
  • Cellule.java : http://pastebin.com/tbX3a2CN
  • Main.java : http://pastebin.com/6P15NW6g

Comme je l'ai déjà expliqué, la Cellule stocke uniquement la valeur et la référence vers la Cellule suivante.
La liste elle, gère l'ajout etc ... (Je garde aussi la référence vers la dernière cellule, histoire de pouvoir ajouter à la fin beaucoup plus facilement)

Je n'ai pas regarder en détail ton code, mais fait attention à tes indices. Par exemple, k.length() s'il renvoie 2, alors les indices sont 0 et 1 , pas 1 et 2.

Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 17:09:17

ah si si ça c'est tout mon code mec ! ça plus le truc que j'ai mis au 1er post te c'est tout :ok:

merci en tout cas ! :ok:

Message édité le 02 janvier 2015 à 17:10:18 par Vexallus
Vexallus
Vexallus
Niveau 10
02 janvier 2015 à 17:44:52

ah c'est bon en fait c'est parce que le mot il commence à 0 normalement
j'ai mis quelques petits affichages de debug et en fait : mon i démarre à 1 (je sais plus pourquoi mais ça m'avait semblé logique de pas mettre '0' cette fois) alors qu'en fait un String bah ça démarre à 0 (et du coup vu que j'avais mis i inférieur OU ÉGAL à la longueur du String croyant ainsi prendre tous les caractères bah j'en prenais même un de trop et j'allais dans de ma mémoire qui était pas du programme du coup j'crois !=

Voici mon code corrigé du coup : http://pastebin.com/YS9dyxFE (là normalement ça marche ça prend bien mais quand je fais afficher la liste, en ayant rentré "54" ça me met 2 fois '4', je crois que même en copiant la liste ça revient pasa ua début)

comment je peux revenir en arrière dans une liste ?

pour les cellules j'ai regardé je comprends pas bien, c'est toujours des listes chaînées ?

EDIT : j'ai vérifié ça met bien lestrucs dans une liste mais juste une fois que je suis arrivé au début je sais pas comment revenir à la tête parce que "tête" en fait ça fait que sélectionner la valeur de l'élément de la liste sur lequel on est actuellement :doute:

Message édité le 02 janvier 2015 à 17:48:14 par Vexallus
TheMightyEagle
TheMightyEagle
Niveau 1
02 janvier 2015 à 19:28:10

Le 02 janvier 2015 à 17:44:52 Vexallus a écrit :
EDIT : j'ai vérifié ça met bien lestrucs dans une liste mais juste une fois que je suis arrivé au début je sais pas comment revenir à la tête parce que "tête" en fait ça fait que sélectionner la valeur de l'élément de la liste sur lequel on est actuellement :doute:

C'est parce que ta méthode tete ne renvoie pas la tête de liste :ok:

Schématiquement, un modèle simple de liste donnerait pour 100 éléments
(Elem1)->(Elem2)->....->(Elem99)->(Elem100) avec Elem1 ton élément de tête et Elem100 ton élément de queue.

Insérer revient donc à modifier la référence de l'élément de queue en instanciant un nouvel élément ayant la bonne valeur. Dit plus simplement si je veux ajouter (Elem101) à la liste précédente je dois :

  1. "Créer" un élément qui porte la bonne valeur (en fait faire un new Liste(101,null))
  2. Faire en sorte que l'attribut "suivant" d'Elem100 contienne la référence d'Elem101 (c'est la méthode setCelluleSuiv proposée par Ryviel)
  3. Faire en sorte que l'attribut "Queue" contienne la référence d'Elem101 (méthode ajouterFin proposée par Ryviel)

Là, d'après ce que j'ai compris de ton code, ta méthode inser modifie la valeur ta cellule courante avec celle de la nouvelle valeur... et renvoie une référence à la cellule suivante ? (celle là même qui aurait du contenir la nouvelle valeur :ouch2:)
Si on déroule ton propre algorithme on alors pour 54 :

  • Instancier une liste ayant comme première valeur 0 (la liste ressemble alors à : (0))
  • "Insérer" la valeur 5, ce qui modifie la valeur du premier élément de ta liste ( la liste devient : (5) )
  • "Insérer" la valeur 4, même chose, (la liste vaut alors : (4))

Alors maintenant, pourquoi as tu deux fois la valeur 4 qui s'affiche ? Soit je n'ai pas vu où dans ton code tu instancie l'élément suivant (si tu as gardé ta fonction inser telle que tu l'as postée tout à l'heure), soit il y a une erreur dans ta boucle de lecture.

Essaye vraiment de relire et surtout comprendre l'explication et le morceau de code de ryviel. :ok:

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment