Bubble sort funkar inte..?
Jag vill sortera kontona baserat på saldo under metoden SorteraBank(). Ska använda bubble sort. Får det inte att fungera. Får felmeddelandet System.NullReferenceException:"Objektreferensen har inte angetts till en instans av ett objekt".
Någon som kan se vad som är fel? Väldigt tacksam för hjälp!
namespace Slutprojekt
{
class Konton // Information som berör kontona
{
private string namn;
private double saldo;
private string kön;
public Konton(string namn, double saldo, string kön)
{
this.namn = namn;
this.saldo = saldo;
this.kön = kön;
}
public string Namn
{
get { return namn; }
set { namn = value; }
}
public double Saldo
{
get { return saldo; }
set { saldo = value; }
}
public string Kön
{
get { return kön; }
set { kön = value; }
}
public string KvinnaEllerMan() // För att tilldela valen x eller y "kön"
{
switch(kön)
{
case "X":
case "x":
{
kön = "Kvinna";
break;
}
case "Y":
case "y":
{
kön = "Man";
break;
}
}
return kön;
}
}
class Banken
{
// Deklarerar variabler
public int antal_konton;
Konton[] konto = new Konton[10];
public double högtSaldoGräns = 100000;
public double lågtSaldoGräns = 10000;
public void LäggTillKonto()
{
// Deklarerar variabler
string namn = "";
double saldo = 0;
string kön = "";
ConsoleKeyInfo userInput;
Console.Clear();
Console.WriteLine(":::::: Lägg till nytt konto ::::::");
if (antal_konton == 10) // Om banken är full
{
Console.WriteLine("\nBanken är tyvärr full.");
}
else
{
while (true) // Ange namn
{
Console.Write("Ange namn: ");
try
{
namn = Console.ReadLine();
break;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
while (true) // Ange saldo
{
Console.Write("Saldo: ");
try
{
saldo = double.Parse(Console.ReadLine());
break; // korrekt inmatning
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
while (true)
{
Console.Write("Välj kön \n[X] Kvinna \n[Y] Man \n");
try
{
userInput = Console.ReadKey(true);
kön = Convert.ToString(userInput.Key);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (kön == "X" || kön == "Y")
{
break; // korrekt inmatning
}
else
{
Console.WriteLine("Detta är inget alternativ. Försök igen.");
}
}
for (int i = 0; i < konto.Length; i++)
{
if (konto[i] == null)
{
konto[i] = new Konton(namn, saldo, kön); // lagra användarens svar
antal_konton++; // öka antalet konton
Console.WriteLine();
Console.WriteLine("Du har nu lagt till ett nytt konto.");
break;
}
else
{
continue;
}
}
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void SkrivUtKonton()
{
Console.Clear();
Console.WriteLine(":::::: NUVARANDE KONTON ::::::");
Console.WriteLine();
int kontoIndex = 0;
foreach (Konton personer in konto) // skriv ut samtliga konton
{
kontoIndex++;
if (personer == null)
{
Console.WriteLine("Konto {0}: Detta konto är för nuvarande tomt.", kontoIndex);
}
else
{
Console.WriteLine("Konto {0}: {1}, {2} :- , {3} ", kontoIndex, personer.Namn, personer.Saldo, personer.KvinnaEllerMan());
}
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void RäknaTotaltSaldo()
{
Console.Clear();
Console.WriteLine(":::::: BANKENS TOTALA SALDO ::::::");
double totaltSaldo = 0;
foreach (Konton personer in konto)
{
if (personer == null)
{
continue; // kontot är tomt
}
else
{
totaltSaldo += personer.Saldo;
}
}
Console.WriteLine("Bankens totala saldo av nuvarande konton är {0} :-", totaltSaldo);
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void BeräknaGenomsnittligtSaldo()
{
Console.Clear();
Console.WriteLine("::::: BANKENS GENOMSNITTLIGA SALDO :::::");
// Deklarerar variabler
int antalKonton = 0;
double totaltSaldo = 0;
foreach (Konton personer in konto)
{
if (personer == null)
{
continue; // kontot är tomt
}
else
{
totaltSaldo += personer.Saldo;
antalKonton++;
}
}
Console.WriteLine("Bankens genomsnittliga saldo är {0} :-", Math.Round(totaltSaldo / antalKonton)); // skriv ut saldot och avrunda
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void HögstaSaldo()
{
Console.Clear();
Console.WriteLine("::::: BANKENS HÖGSTA SALDO ::::: ");
double högstSaldo = 0;
foreach (Konton plats in konto) // Jämför saldona i de nuvarande kontona
{
if (plats == null)
{
continue;
}
else if (plats.Saldo >= högstSaldo)
{
högstSaldo = plats.Saldo;
}
else
{
continue;
}
}
foreach (Konton saldo in konto)
{
if ( saldo == null)
{
continue;
}
else if(saldo.Saldo == högstSaldo)
{
Console.WriteLine("\nBankens högsta saldo är {0} :-" , saldo.Saldo);
}
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void SökSaldo()
{
Console.Clear();
Console.WriteLine("::::: HITTA KONTO MED SPECIFIKT SALDO :::::");
// Deklarerar variabler
double sökSaldoMax = 0;
double sökSaldoMin = 0;
int antalKonton = 0;
int kontoIndex = 0;
while (true)
{
Console.Write(" \nAnge minsta önskat saldo: ");
try
{
sökSaldoMin = double.Parse(Console.ReadLine());
break;
}
catch (FormatException)
{
Console.WriteLine("\nVar god ange siffror");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
while(true)
{
Console.Write(" Ange högsta önskat saldo: ");
try
{
sökSaldoMax = double.Parse(Console.ReadLine());
if (sökSaldoMax < sökSaldoMin)
{
Console.WriteLine("\nVar god ange ett högre saldo");
}
else
break;
}
catch (FormatException)
{
Console.WriteLine("\nVar god ange siffror");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
foreach (Konton matchningar in konto)
{
kontoIndex++;
if (matchningar == null)
{
continue; // finns inget konto på denna plats
}
else if (matchningar.Saldo >= sökSaldoMin & matchningar.Saldo <= sökSaldoMax) // konton som ligger inom spannet
{
Console.WriteLine("Konto {0}: {1} :-", kontoIndex, matchningar.Saldo);
antalKonton++;
}
}
if (antalKonton == 0)
{
Console.WriteLine("\nDet finns inga konton inom detta spann");
}
else
{
Console.WriteLine("\nDet finns {0} konton som matchar din sökning", antalKonton);
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void SorteraBank()
{
Console.Clear();
Console.WriteLine(":::::: SORTERA BANKEN EFTER SALDO ::::::");
for (int i = 0; i <= konto.Length-1; i++) //Sortera med hjälp av bubble sort
{
for (int j = 0; j <= (konto.Length -1)-i; j++)
{
double temporärtSaldo = 0;
string temporärtNamn = "";
string temporärKön = "";
if (konto[j + 1] == null )
{
continue;
}
else if (konto[j].Saldo > konto[j + 1].Saldo)
{
temporärtNamn = konto[j + 1].Namn;
konto[j + 1].Namn = konto[j].Namn;
konto[j].Namn = temporärtNamn;
temporärtSaldo = konto[j + 1].Saldo;
konto[j + 1].Saldo = konto[j].Saldo;
konto[j].Saldo = temporärtSaldo;
temporärKön = konto[j + 1].Kön;
konto[j + 1].Kön = konto[j].Kön;
konto[j].Kön = temporärKön;
}
}
}
foreach(Konton personer in konto)
{
if(personer == null)
{
continue;
}
else
{
Console.WriteLine("{1} :-", personer.Saldo);
}
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
}
public void SkrivUtKön()
{
Console.Clear();
Console.WriteLine("::::: KÖN PÅ KONTOINNEHAVARE :::::");
int innehavareNummer = 0;
foreach (Konton person in konto)
{
innehavareNummer++;
if (person == null)
{
continue; // tomt konto
}
else
{
Console.WriteLine("Konto {0}: Detta konto ägs av en {1}", innehavareNummer, person.KvinnaEllerMan());
}
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
// vilka positioner har manliga/kvinnliga innehavare
}
public void Granska()
{
Console.Clear();
Console.WriteLine(":::::: GRANSKA KONTON ::::::");
int nummer = 0;
int i = -1;
foreach (Konton person in konto) // skriv ut alla konton
{
nummer++;
if (person == null)
{
continue;
}
else
{
Console.WriteLine("Konto {0}: {1}, {2} :-, {3}", nummer, person.Namn, person.Saldo, person.KvinnaEllerMan());
}
}
Console.Write("Välj nummer på det konto som du önskar granska: ");
while (true)
{
try
{
i = int.Parse(Console.ReadLine()) - 1;
if (i < 0 || i >= konto.Length)
{
Console.WriteLine("Var god välj ett nummer mellan {0} och {1}");
}
else if (konto[i] == null)
{
Console.WriteLine("Inget konto finns registrerat på detta nummer");
}
else
{
break;
}
}
catch (FormatException)
{
Console.WriteLine("Var god ange ett heltal.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
if (konto[i].Saldo < lågtSaldoGräns)
{
Console.WriteLine("\nOj, här var det inte mycket pengar...De tidigare pengarna på kontot har nyss använts till att reparera föreningens liftsystem.");
}
else if (konto[i].Saldo >=lågtSaldoGräns & konto[i].Saldo < högtSaldoGräns)
{
Console.WriteLine("\nÄgaren av det här kontot är nybliven sponsor i föreningen!");
}
else if (konto[i].Saldo < högtSaldoGräns & konto[i].Saldo > lågtSaldoGräns)
{
Console.WriteLine("\nDet här kontot ägs av en trofast sponsor!");
}
else if (konto[i].Saldo >= högtSaldoGräns)
{
Console.WriteLine("\nWow! Med såhär mycket pengar kan föreningen känna sig trygg!");
}
Console.WriteLine();
Console.WriteLine("Tryck valfri tangent för att återvända till huvudmenyn...");
Console.ReadKey(true);
//
// hur reagerar kontonas innehavare när man granskar kontot? Basera på namn, saldo eller kön
}
public void StängKonto()
{
Console.Clear();
Console.WriteLine(":::::: RADERA KONTO ::::::");
int nummer = 0;
int i = -1;
foreach(Konton person in konto)
{
nummer++;
if(person == null)
{
Console.WriteLine("Konto {0}: Den här platsen är ledig", nummer);
}
else
{
Console.WriteLine("Konto {0}: {1}, {2} :- , {3}", nummer, person.Namn, person.Saldo, person.KvinnaEllerMan());
}
}
Console.Write("Ange numret på det konto som du önskar radera: ");
while(true)
{
try
{
i = int.Parse(Console.ReadLine()) - 1;
antal_konton--;
if (i < 0 || i >= konto.Length)
{
Console.WriteLine("Var god ange ett nummer mellan 1 och {0}", konto.Length);
}
else if (konto[i] == null)
{
Console.WriteLine("Den här platsen är redan tom. Var god välj ett nummer med ett registrerat konto");
}
else
break;
}
catch(FormatException)
{
Console.WriteLine("Var god ange ett heltal.");
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Console.WriteLine();
Console.WriteLine("Konto {0} har nu raderats.", i + 1);
konto[i] = null;
Console.WriteLine("Tryck ned valfri tangent för att återvända till huvudmenyn");
Console.ReadKey(true);
//kod för att avsluta ett konto
}
public void Run()
{
while(true)
{
// meny med de olika valen
Console.Clear();
Console.WriteLine("Välkommen till Banken!");
Console.WriteLine("\nVad vill du göra?");
Console.WriteLine("\n[A] LÄGG TILL ETT KONTO ");
Console.WriteLine("[B] STÄNG ETT KONTO ");
Console.WriteLine("[C] SE INFORMATION OM LAGRADE KONTON ");
Console.WriteLine("[D] SE BANKENS TOTALA SALO ");
Console.WriteLine("[E] SE BANKENS GENOMSNITTLIGA SALDO ");
Console.WriteLine("[F] SE BANKENS HÖGSTA SALDO ");
Console.WriteLine("[G] SÖK KONTON BASERAT PÅ SALDO ");
Console.WriteLine("[H] SORTERA BANKEN BASERAT PÅ SALDO ");
Console.WriteLine("[I] SE VILKA KONTON SOM ÄGS AV KVINNLIGA/ MANLIGA INNEHAVARE ");
Console.WriteLine("[J] GRANSKA ETT KONTO ");
Console.WriteLine("[K] STÄNG BANKEN ");
ConsoleKeyInfo svar = Console.ReadKey(true);
switch (svar.Key)
{
case ConsoleKey.A:
{
LäggTillKonto();
break;
}
case ConsoleKey.B:
{
StängKonto();
break;
}
case ConsoleKey.C:
{
SkrivUtKonton();
break;
}
case ConsoleKey.D:
{
RäknaTotaltSaldo();
break;
}
case ConsoleKey.E:
{
BeräknaGenomsnittligtSaldo();
break;
}
case ConsoleKey.F:
{
HögstaSaldo();
break;
}
case ConsoleKey.G:
{
SökSaldo();
break;
}
case ConsoleKey.H:
{
SorteraBank();
break;
}
case ConsoleKey.I:
{
SkrivUtKön();
break;
}
case ConsoleKey.J:
{
Granska();
break;
}
case ConsoleKey.K:
{
Environment.Exit(0);
return;
}
default:
{
Console.WriteLine("Var vänlig välj ett av alternativen i menyn");
break;
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
var Banken = new Banken();
Banken.Run();
Console.ReadKey(true);
}
}
}
Snyggt indenterat och allt, men kan du visa hela felmeddelandet?
'Slutprojekt.exe' (CLR v4.0.30319: DefaultDomain): Loaded 'C:\Users\Tess\source\repos\Slutprojekt\Slutprojekt\bin\Debug\Slutprojekt.exe'. Symbols loaded.
'Slutprojekt.exe' (CLR v4.0.30319: Slutprojekt.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_sv_b77a5c561934e089\mscorlib.resources.dll'. Module was built without symbols.
Exception thrown: 'System.IndexOutOfRangeException' in Slutprojekt.exe
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in Slutprojekt.exe
Indexet låg utanför gränserna för matrisen.
Menar du detta?
Fick ett annat felmeddelande förut, det som står i originalinlägget, när jag testade att tillfälligt ta bort if (konto[j + 1] == null )
Jag tänkte att felmeddelandet kanske sa nåt om var i koden det hände.
Hur ser dina indata ut, exakt?
Jag ser två saker jag tror är fel:
Du loopar som mest j upp till length-1 (när i=0), dvs högsta indexet. Men sedan gör du en koll på konto[j+1], vilket ibland då är utanför högsta index, vilket lär orsaka error. Det ska väl bli rätt om du ändrar <= till < i for-looparna.
Dessutom kollar du visserligen ifall koton[j+1]==null, men inte ifall konto[j]==null, så du riskerar därmed att försöka läsa null.Saldo.
EDIT: Och du behöver bestämma var du ska lägga null-kontona (först eller sist), för om du bara hoppar över så blir det ingen jämförelse av två saldo med null mellan sig, och risken blir att inget sorteras. För att slippa flytta null kan du nog inte använda just bubblesort.
(Slutligen så bör du väl för snabb bubblesort ha en flagga som kollar ifall inget byte skett i j-loopen, och isåfall avbryter i-loopen, men det fungerar ju ändå.)
Tack för hjälpen! Det löste sig när jag ändrade det som du skrev jek7 ☺️