webForumDet fria alternativet

Sortera array + flytta värden i arrayen

4 svar · 935 visningar · startad av Broms

BromsMedlem sedan sep. 2002188 inlägg
#1

Sitter med ett litet program som ska fungera som en databas.. Man lägger till personer i ett register, och kan sedan göra diverse utskrifter, t.ex. utskrift av en/alla personer, sökning av person, uppdatering av information om en person..

Det jag har problem med är:

1. om man tar bort en person, då ska ju alla platser bakom denna, i arrayen, flytta fram ett steg. Säkert inte så smidigt sätt att göra det på, men men..

2. Hur sorterar jag arrayen? Jag vill att den skall sortera efter bokstavsordning på namnet..? Har börjat med definitionen av metoden.

Hjälp please?

Kod:

Person.java

class Person {
	
	// Instansvariabler
	private String namn;
	private String anvnamn;
	private long personnummer;
	
	// Konstruktor
	public Person(String n, String n2, long pnr){
		namn = n;
		anvnamn = n2;
		personnummer = pnr;
		}
		
	public void ändraPnr(long pnr){
		//Ändra personnummer
		personnummer = pnr;
	}
	
	public String Namn(){
		//Returnera personens förnamn
		return namn;
	}
	
	public String anvNamn(){
		//Returnera personens efternamn
		return anvnamn;
	}
	
	public long pNr(){
		//Returnera personens personnummer
		return personnummer;
	}
	
	public String toString(){
		//Returnera all info om en Person
		String S;
		S = "Namn: " + namn + " Anv.namn: " + anvnamn + " Personnummer: "+ personnummer;
		return S;
	}
}

Personregister.java

import extra.*;
class Personregister {
	
	// INSTANSVARIABLER
	Person [] Personer;
	int antalpersoner;
	
	// KONSTRUKTOR
	public Personregister(int antal){
		
		Personer = new Person[antal];	//Skapa fält av böcker
		antalpersoner = antal;
	}

	// METODER
//LÄGG TILL Person
	public void läggTill(int i, String n, String n2, long pnr){
		//Lägg till en person på position i
		Personer[i] = new Person(n,n2,pnr);
	}

//RETURNERAR index på en persons anv.namn
	public int returNamn(String n){
		//Returnera personindex given anv.namn
		int i = 0;
		while(i < antalpersoner){
			if (Personer[i].anvNamn().equals(n))
				return i;
				i++;
		}
	Std.out.println("Personen existerar ej i databasen!");	
	return 9999;
	}
//RETURNERAR index på en persons personnummer
	public int returPnr(long p){
		//Returnera personindex given personnummer
		int i = 0;
		while(i < antalpersoner){
			if (Personer[i].pNr() == p)
				return i;
				i++;
		}
	Std.out.println("Personen existerar ej i databasen!");	
	return 999;
	}

//SÖK - lämnar all info om en person
	// Namnsök
	public void sokNamn(String n){
		//Skriv ut alla personer med anv.namnet n
		int i = 0;
		Std.out.println("Alla personer med namnet: " + n + ": \n\n");
		while(i < antalpersoner){
			if (Personer[i].Namn().equals(n))
				Std.out.println("\n" + toString(i) + "\n");
			i++;
		}
	}
	
//TA BORT person
	public void taBort(int p){
		//ta bort person med index p
		for(int i=p-1; p<antalpersoner-1; i++){
			Personer[i]=Personer[i+1];
		}
	}
	
//SORTERA ARRAY
	public void Sortera(){
		//ta bort person med index p
		for(int i=0; i<antalpersoner; i++){
			//HUR??!??!			
		}
	}
	
//UTSKRIFT
	//En/flera personer
	public String toString(int i){
		String S;
		S = "Namn: " + Personer[i].Namn() + "\nAnv.namn: " + Personer[i].anvNamn() + "\nPersonnummer: " + Personer[i].pNr();
		return S;
	}
	//Alla personer
	public void skrivAlla(int a){
		for (int i=0; i<a; i++){
			String S;
			S = "Namn: " + Personer[i].Namn() + "\nAnv.namn: " + Personer[i].anvNamn() + "\nPersonnummer: " + Personer[i].pNr();
			Std.out.print(S + "\n\n");
		}Std.out.print("\n\n");
	}
	
//ÄNDRA personnummer
	public void ändraPnr(int i, long Pnr){
		Personer[i].ändraPnr(Pnr);
	}
}

Personregistertest.java

import extra.*;
class Personregistertest {

public static void main(String[] arg) {
	int MAX=1000,i=0,val=0, count=0;
	long pnr;
	String namn,anvnamn;
	// Skapar nytt personregister
	Personregister Register = new Personregister(MAX);
	
	//Fyller registret med slask- info
	//for (;count<MAX; count++){
	//	Register.läggTill(count,"aaaaa","aaaaa",0);
	//}
	
	Std.out.println("Välkommen till personregister.net!\n");	

		while(val!=7){
		String temp;
		long templong;
		int tempint;
		val = meny();
		
		switch(val){
			
			case 1:
			Std.in.skipLine();		
			Std.out.println("Ange för- och efternamn: " );
			namn = Std.in.readLine();
			Std.out.println("Ange användarnamn: " );
			anvnamn = Std.in.readLine();	
			Std.out.println("Ange Personnummer: " );
			pnr = Std.in.readLong();
		
			// Lägger till personen i registret
			if(i<MAX){
				Register.läggTill(i,namn,anvnamn,pnr);
				i++;
				}
			else Std.out.println("Registret är fullt!");
			break;

			//<-- VARFÖR FUNGERAR DET INTE? -->
			case 2:
			//Ta bort person
			Std.out.println("\nAnge personnummer: ");
			Std.in.skipLine();
			templong = Std.in.readLong();
			tempint = Register.returPnr(templong);
			Register.taBort(tempint);
			break;
			
			case 3:
			//Sök person
			Std.out.println("\nAnge för- och efternamn: ");
			Std.in.skipLine();
			temp = Std.in.readLine();
			Register.sokNamn(temp);
			break;
			
			case 4:
			//Ändra personnummer
			Std.in.skipLine();
			Std.out.println("\nVilken person(anv.namnet!) Vill du ändra personnummer på? ");
			temp = Std.in.readLine();
			Std.out.println("\nVilket är det nya personnumret? ");
			templong = Std.in.readLong();
			tempint = Register.returNamn(temp);
			Register.ändraPnr(tempint,templong);
			break;

			//<-- HUR KONSTRUERAR JAG DENNA? -->
			case 5:
			//Sortera arreyen
			//Register.Sortera();
			break;

			case 6:
			//Skriv ut arrayen
			Std.out.println("Alla personer i registret: \n");
			Register.skrivAlla(i);
			break;
			
			case 7:
			//Avsluta
			Std.out.println("Programmet avslutas..");
			break;
			
			default:
			//Default
			Std.out.println("Felaktigt val!");
			break;
		}
	}
}

// Skriver ut menyn - och returnerar valets värde
public static int meny(){
	int val;
	Std.out.println("1. Lägg till en person");
	Std.out.println("2. Ta bort en person");	
	Std.out.println("3. Sök efter en person");
	Std.out.println("4. Ändra information för en person");
	Std.out.println("5. Sortera registret");
	Std.out.println("6. Skriv ut register");
	Std.out.println("7. Avsluta");
	Std.out.print("Vad vill du göra?");
	val = Std.in.readInt();
	return val;
}
}

Mvh nAkid

spangoMedlem sedan juni 20008 205 inlägg
#2

Re: Sortera array + flytta värden i arrayen

Broms skrev:

1. om man tar bort en person, då ska ju alla platser bakom denna, i arrayen, flytta fram ett steg. Säkert inte så smidigt sätt att göra det på, men men..

Om du kollar på din nuvarande kod:

//TA BORT person
public void taBort(int p){
	//ta bort person med index p
	for(int i=p-1; p<antalpersoner-1; i++){
		Personer&#91;i]=Personer[i+1];
}

Det är rätt tänkt, men vad händer om du säger taBort(0)? Jo, då skyfflar den objektet på index 0 till platsen innan, som har index -1. Det får man inte, så då får du ett ArrayIndexOutOfBoundsException (och det är tragiskt att jag kan namnet på det utantill ;) ). Du ska börja på position p - om du då anropar med taBort(0) kommer Personer[0] skrivas över med Personer[1], Personer[1] med Personer[2] etc. Sen är det också en bra idé (om än inte nödvändigt) att sätta det sista elementet i arrayen till null, annars kommer den sista posten i arrayen förekomma två gånger.

//TA BORT person
public void taBort(int p){
	//ta bort person med index p
	for(int i=p; p<antalpersoner-1; i++){
		Personer&#91;i]=Personer[i+1];
	Personer[antalpersoner - 1] = null;
	antalpersoner--; // räkna ner antal personer eftersom en just togs bort
}

Broms skrev:

2. Hur sorterar jag arrayen? Jag vill att den skall sortera efter bokstavsordning på namnet..? Har börjat med definitionen av metoden.

Hänvisar tillbaka till den tidigare tråden med Collator & c:o ;)
Anpassa compareTo i den klassen så att allt stämmer (det enda som borde behövas ändras är att byta ut anropen av getName() till Name(), om jag inte misstar mig), och sen sorterar du med Arrays.sort:

//SORTERA ARRAY
public void Sortera(){
	Arrays.sort(Personer, 0, antalpersoner); // sortera icke-nullade poster
}
BromsMedlem sedan sep. 2002188 inlägg
#3

okej så jag ska använda mig av stycket:

 private static final Collator SV_SE = Collator.getInstance(new Locale("sv", "se"));

  // lägg till fält, metoder etc. efter behov ...
  
  public int compareTo(Object obj){
    Person other = (Person) obj;
    // jämför namnen:
    return SV_SE.compare(this.Namn(), other.Namn());
  }

}

och klassen måste implementera Comparable..

men i vilken klass ska detta ligga? hur sker anropet av ovanstående?

tidigare tänkte jag mitt anrop i testprogrammet som följande Register.Sortera();, men det nya blir helt enkelt Register.compareTo(), eller ska metoden ligga direkt i Person.java?

PhorpherMedlem sedan feb. 20002 300 inlägg
#4

Metoden ska ligga i din Person-klass. Tänk på vad funktionen gör. Den jämför ett Person-objekt mot ett annat. Sorteringsalgoritmer använder sedan denna CompareTo-metod för att sortera en collection.

spangoMedlem sedan juni 20008 205 inlägg
#5

Så alltså, när du anropar Arrays.sort på din array, kommer den metoden börja hoppa runt i arrayen och använda compareTo för att jämföra objekt. compareTo behöver du normalt inte anropa själv.

137 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
134 ms — hämta tråd, inlägg och bilagor (db)