Vill du vara del av diskussionerna i forumet, ställa frågor eller hjälpa andra? Registrera dig här!
Trädvy Permalänk
Medlem
Registrerad
Jan 2013

Problem med sökfunktion i c#

Hej!
problemet jag har är följande.
Jobbar med vektorer och när man i case 3 får söka efter sitt föremål så söker den igenom alla 5 värdena och skriver ut alla

Hur kan jag med en bool variabel göra så att texten bara skrivs ut en gång istället för flera?

case 3:

Console.WriteLine("Skriv in det du söker\n");
string sök = Console.ReadLine();// sparar användarens inmatning

for (int i = 0; i < rygga.Length; i++)// här använder jag en lista som räknar i index

if (rygga.Length == sök)
{

Console.WriteLine(rygga[i] + "\nHittades i ryggsäcken.\n");

}

else
{
Console.WriteLine("Hittades INTE i ryggsäcken.\n");

}

break;

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

Innan du gör sökningen (for-loopen), skapa en bool som anger om den är hittad eller inte, från början satt till false. Om den hittas, sätt variabeln till true (och avbryt loopen, resten är slöseri med CPU-tid). Sen kollar du bara om variabeln är sann eller inte.

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 48 GB 3200 MHz CL14 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Plats
Umeå
Registrerad
Apr 2009

För att lägga till information på ovan skrivare: Du ska alltså ta bort else I loopen och sätts en till if efter loopen som kikar ditt nya boom-värde du har skapat enligt ovan skrivare.

Chassi: Fractal Design Define R3, Titanium CPU: Intel Core i7 7700K 4.8 GHz
MoBo: Gigabyte GA-Z270-Gaming K3 GPU: Sapphire RX Vega 64 8GB
RAM: Corsair LPX 16GB CL15 3000Mhz VENGEANCE SSD: Samsung 750 EVO 500GB
HDD: 500GB Seagate Barracuda 7200rpm PSU: LEPA B1000-MB

Trädvy Permalänk
Medlem
Plats
127.0.0.1
Registrerad
Sep 2003

Din jämförelse är lite tokig, du ska inte jämföra med ryggans totala längd, utan värdet på de individuella elementen. Du skriver redan ut rygga[i] som innehåller värdet du vill jämföra med, så använd den istället för rygga.Length i din jämförelse.

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

känner mig dum , men jag fattar inte!

vart är det jag ska ändra det till true? för när jag har den inom klammerparentesen så hittar den inte den.
case 3:

Console.WriteLine("Skriv in det du söker\n");
string sök = Console.ReadLine();// sparar användarens inmatning
bool hitta = false;
for (int i = 0; i < rygga.Length; i++)// här använder jag en lista som räknar i index

if (rygga[i] == sök) // om sökningen matchar med listan i index så ska programmet skirva att föremålet hittats.
{

Console.WriteLine("\nHittades i ryggsäcken.\n");

}

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jun 2010
Skrivet av Nissan300zx:

känner mig dum , men jag fattar inte!

vart är det jag ska ändra det till true? för när jag har den inom klammerparentesen så hittar den inte den.
case 3:

Console.WriteLine("Skriv in det du söker\n");
string sök = Console.ReadLine();// sparar användarens inmatning
bool hitta = false;
for (int i = 0; i < rygga.Length; i++)// här använder jag en lista som räknar i index

if (rygga[i] == sök) // om sökningen matchar med listan i index så ska programmet skirva att föremålet hittats.
{

Console.WriteLine("\nHittades i ryggsäcken.\n");

}

Testa:

Console.WriteLine("Skriv in det du söker\n"); string sök = Console.ReadLine();// sparar användarens inmatning bool hitta = false; for (int i = 0; i < rygga.Length; i++)// här använder jag en lista som räknar i index if (rygga[i] == sök) // om sökningen matchar med listan i index så ska programmet skirva att föremålet hittats. { hitta = true; break; } } if(hitta) Console.WriteLine("\nHittades i ryggsäcken.\n"); else Console.WriteLine("\nHittades INTE i ryggsäcken.\n");

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av snajk:

Testa:

Console.WriteLine("Skriv in det du söker\n"); string sök = Console.ReadLine();// sparar användarens inmatning bool hitta = false; for (int i = 0; i < rygga.Length; i++)// här använder jag en lista som räknar i index if (rygga[i] == sök) // om sökningen matchar med listan i index så ska programmet skirva att föremålet hittats. { hitta = true; break; } } if(hitta) Console.WriteLine("\nHittades i ryggsäcken.\n"); else Console.WriteLine("\nHittades INTE i ryggsäcken.\n");

Är tanken att den ska bryta loopen vid första träff eller ska den lista ut alla träffar?
Sedan kan jag tillägga att sökningen just nu är case sensitive, söker du på "katt" så kommer du inte få en träff på ordet "Katt".

if(string.Equals(rygga[i], sök, StringComparison.OrdinalIgnoreCase) { ... }

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2012
Skrivet av zaibuf:

Är tanken att den ska bryta loopen vid första träff eller ska den lista ut alla träffar?
Sedan kan jag tillägga att sökningen just nu är case sensitive, söker du på "katt" så kommer du inte få en träff på ordet "Katt".

if(string.Equals(rygga[i], sök, StringComparison.OrdinalIgnoreCase) { ... }

För att tillägga ett alternativ för case insensitive jämförelse som jag (lat som man är) brukar köra på:

if(rygga[i].ToLower() == sök.ToLower())

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jun 2010
Skrivet av zaibuf:

Är tanken att den ska bryta loopen vid första träff eller ska den lista ut alla träffar?
Sedan kan jag tillägga att sökningen just nu är case sensitive, söker du på "katt" så kommer du inte få en träff på ordet "Katt".

if(string.Equals(rygga[i], sök, StringComparison.OrdinalIgnoreCase) { ... }

Tja break är väl inte helt nödvändig förstås, samtidigt, om uppgiften är att kontrollera om ett värde finns i en array så spelar det ingen roll om det finns flera gånger. Att använda IgnoreCase kan ju vara korrekt men det kan också vara helt fel. Jag vet att jag har fått fel när jag pluggade i liknande fall där man försökte vara extra smart liksom. Att ge positivt svar för katt när man söker efter Katt är ju inte nödvändigtvis korrekt.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av toobypls:

För att tillägga ett alternativ för case insensitive jämförelse som jag (lat som man är) brukar köra på:

if(rygga[i].ToLower() == sök.ToLower())

Tänk på att denna konvertering kommer att köras för båda strängarna vid varje iteration. Är det många jämförelser kan det vara väldigt tungt att köra. ToLower fungerar inte heller för alla språk då visa konverteringar kan bli knasiga.

Skrivet av snajk:

Tja break är väl inte helt nödvändig förstås, samtidigt, om uppgiften är att kontrollera om ett värde finns i en array så spelar det ingen roll om det finns flera gånger. Att använda IgnoreCase kan ju vara korrekt men det kan också vara helt fel. Jag vet att jag har fått fel när jag pluggade i liknande fall där man försökte vara extra smart liksom. Att ge positivt svar för katt när man söker efter Katt är ju inte nödvändigtvis korrekt.

Står bara "Sök i ryggsäcken" i menyvalet, jag vet inte kraven på själva uppgiften.
Jag sa det bara som en poängtering så att TS inte sitter och söker på "katt" och förväntas få match på ett föremål av "Katt".
Givetvis får det anpassas till uppgiften och det behöver inte vara korrekt

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2012
Skrivet av zaibuf:

Tänk på att denna konvertering kommer att köras för båda strängarna vid varje iteration. Är det många jämförelser kan det vara väldigt tungt att köra. ToLower fungerar inte heller för alla språk då visa konverteringar kan bli knasiga.

Yep, medveten om det och väldigt relevant input till mitt alternativ. Därav ville jag påpeka att det är ett "lazy-alternativ"

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

Tack så hemskt mycket för all hjälp!. Övningen ska bara bryta när jag hittar det jag söker på istället för att ge 5 svar där 4 inte hittades utan det ena

Nu är bilden borta som jag la upp,men tex om jag söker efter något i arrayen på plats 3 så skriver den ut

hitta inte
hitta inte
hitta
hitta inte
hitta inte.

vill att den ska sluta söka när den hittats.

hur är det med listor? funkar sökningen på samma sätt?

uppgiften blev godkänd.

Trädvy Permalänk
Medlem
Plats
Söderbärke
Registrerad
Nov 2010
Skrivet av Nissan300zx:

Tack så hemskt mycket för all hjälp!. Övningen ska bara bryta när jag hittar det jag söker på istället för att ge 5 svar där 4 inte hittades utan det ena

Nu är bilden borta som jag la upp,men tex om jag söker efter något i arrayen på plats 3 så skriver den ut

hitta inte
hitta inte
hitta
hitta inte
hitta inte.

vill att den ska sluta söka när den hittats.

hur är det med listor? funkar sökningen på samma sätt?

uppgiften blev godkänd.

Prova använda break; när du hittat rätt värde. Det avbryter den närmsta loopen.

För listor har du contains https://docs.microsoft.com/en-us/dotnet/api/system.collection...

if(dinLista.Contains(valueToFind)) { ... }

Kod skriven på telefonen, ursäkta om det ser kaos ut.

Nörd, utvecklare, pappa, löpartokig, vegan och besserwisser.

Bli vegan! För djuren, planeten, hälsan och våra barns skull!

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

@NisseG91:

Console.WriteLine("skriv in det du söker: ");
string sök = Console.ReadLine();
for (int i = 0; i < Loggboken.Count; i++)

if (Loggboken.Contains(sök))

Console.WriteLine("Loggboken hittade följande: " + Loggboken[i]);

Jag vill helst undvika contains metoden då jag inte riktigt förstår den. Men å andra sidan verkar jag inte fatta riktigt det här med sökning.

När jag gör en linjär sökning här ovan så säger den bara "can not convert from string to string[] ??

samma problem när jag kör denna

[ code ]
Console.WriteLine("skriv in det du söker: ");
string sök = Console.ReadLine();
for (int i = 0; i < Loggboken.Count; i++)

if (Loggboken[i] == sök)

Console.WriteLine("Loggboken hittade följande: " + Loggboken[i]);
[ /code]

Trädvy Permalänk
Medlem
Registrerad
Nov 2011

@Nissan300zx:
Contains gör en linjär sökning, så du behöver inte ha någon for-loop runt Loggboken.Contains(sök); det blir bara kaka på kaka.

För övrigt tror jag inte att ditt felmeddelande rör den biten kod då Loggboken[i] returnerar en string (såvida du inte har skapat en "jagged array", d.v.s. en array av arrayer).

Visual Studio borde tala om för dig vilken rad som felar, dubbelkolla den.

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av Nissan300zx:

@NisseG91:

Console.WriteLine("skriv in det du söker: ");
string sök = Console.ReadLine();
for (int i = 0; i < Loggboken.Count; i++)

if (Loggboken.Contains(sök))

Console.WriteLine("Loggboken hittade följande: " + Loggboken[i]);

Jag vill helst undvika contains metoden då jag inte riktigt förstår den. Men å andra sidan verkar jag inte fatta riktigt det här med sökning.

När jag gör en linjär sökning här ovan så säger den bara "can not convert from string to string[] ??

samma problem när jag kör denna

[ code ]
Console.WriteLine("skriv in det du söker: ");
string sök = Console.ReadLine();
for (int i = 0; i < Loggboken.Count; i++)

if (Loggboken[i] == sök)

Console.WriteLine("Loggboken hittade följande: " + Loggboken[i]);
[ /code]

Låter som din lista innehåller arrayer, alltså List<string[]>. Det innebär att du måste gå en nivå djupare för att söka mot strängarna. Simplaste är att nästa två for loopar.

Trädvy Permalänk
Medlem
Plats
Götet
Registrerad
Okt 2013

Du har fått bra svar angående sökningar, så jag kommer bara med ett generellt tips inför framtida programmering. Blanda inte språk i koden!

Välj ett språk, och håll dig till det. Gäller både kommentarer och variabler/metoder. Mycket lättare att läsa och förstå koden då.

Och använd code-taggen när du postar kod i forum så får du anyo formatering

Ju lättare vi läsare förstår vad du gjort, desto bättre svar kommer du att få.
Lycka till!

Processor: Motorola 68000 | Klockfrekvens: 7,09 Mhz (PAL) | Minne: 256 kB ROM / 512 kB RAM | Bussbredd: 24 bit | Joystick: Tac2 | Operativsystem: Amiga OS 1.3

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Jun 2010

@Nissan300zx: Du bör läsa på lite om skillnaderna mellan en List<> och en Array[] (som svenska progrmmeringslärare verkar vilja kalla för vektor trots att det redan finns Vector i C#). I praktiken kan de ju användas ganska likt, den stora skillnaden är att en array har en viss storlek medan en lista inte har det utan går att lägga till till.

Trädvy Permalänk
Medlem
Plats
Örebro
Registrerad
Jan 2011

Den lärare som säger Vektor om Array borde få sparken på direkten... Sååå många problem det skapar för de stackars eleverna.

He who hasn't hacked assembly language as a youth has no heart. He who does so as an adult has no brain.
~John Moore

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

Tack för alla era svar!
Jag har stött på ett annat problem
varför upprepas min sökning om om igen. Hur kommer jag runt det?

Nu ser det ut såhär.

Så här ser min kod ut.

static void Main(string[] args) { List<string[]> Loggboken = new List<string[]>(); string[] logg = new string[2]; bool meny = true; Console.WriteLine("\nVälkommen till loggboken. Välj en siffra 1-4:\n "); while (meny) { Console.WriteLine("[1]Skriv ut alla loggar: "); Console.WriteLine("[2]Skriv nytt inlägg i loggboken: "); Console.WriteLine("[3]Sök inlägg i loggboken: "); Console.WriteLine("[4]Avsluta loggboken: "); int.TryParse(Console.ReadLine(), out int valavmeny); switch (valavmeny) { case 1: if (Loggboken.Count == 0) { Console.WriteLine("Loggboken är tom för tillfället.\n"); } foreach (string[] item in Loggboken) { foreach (var inlägg in item) { Console.WriteLine(inlägg); } } break; case 2: logg = new string[2]; Console.WriteLine("\nSkriv in en titel: "); logg[0] = Console.ReadLine(); Console.WriteLine("\nSkriv ett inlägg: "); logg[1] = Console.ReadLine(); Loggboken.Add(logg); Console.WriteLine(); break; case 3: Console.WriteLine("skriv in det du söker: "); string sök = Console.ReadLine(); bool hitta = false; for (int i = 0; i < Loggboken.Count; i++) if (sök == logg[0] || sök == logg[1]) {Console.WriteLine("\nTitel: " +logg[0] +"\nInlägg: " + logg[1]); hitta = true; } else if (!hitta) { Console.WriteLine("Finns INTE i Loggboken."); } break; case 4: Console.WriteLine("Du har valt att lämna loggboken. Hejdå!"); meny = false; break; default: Console.WriteLine("Något gick snett! Försök med en siffra 1-4"); break; } } } } }

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

Tänk igenom vad denna raden gör:

if (sök == logg[0] || sök == logg[1])

Är det verkligen det du vill testa?
(En hint till: du använder aldrig loopvariabeln i i sökningen. Samt, inte en hint utan observation: "hitta" används inte, men den behövs inte som koden ser ut nu.)

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 48 GB 3200 MHz CL14 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Jun 2007

@Nissan300zx: Ett tips är att ta dig en titt på hur debuggern fungerar, här är en kort guide som går igenom grunderna. Med debuggern kan du se exakt vad din kod gör när den körs, så att lägga några minuter på att lära dig använda den kommer spara dig mycket tid i längden.

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

@Thomas:
Tack=) nu ser jag att den söker igenom loopen.

Men problemet kvarstår.

När jag med hjälp av step in funktion kollar koden så ser jag att den på count i loggboken ändras till 2 när jag matar in två titlar.

Men i sökfunktionen så kommer jag inte åt de jag lagt in tidigare. Utan om programmet ska hitta titeln måste jag skriva in det senaste annars säger den hittade inte.

Hur löser jag det problemet? står verkligen helt tomt i huvudet. Jag har suttit flertals timmar med detta men fan koda är nog för svårt för mig.

om jag redan i case 2: lagt till Loggboken.add(post) borde inte detta spara alla loggar separat? istället så känns det som att den sparar loggarna men istället för att logga var för sig så skriver den över det föregående å sparar den +1. så jag får hela tiden nya counts men med samma text++.

case 3: Console.WriteLine("skriv in Titeln du vill söka på: "); string sök = Console.ReadLine(); bool hitta = false; for (int i = 0; i < Loggboken.Count; i++) if (sök == logg[i]) { hitta = true; Console.WriteLine("\nTitel: " +logg[0] +"\nInlägg: " + logg[1]); Console.WriteLine(); } else if (!hitta) { hitta = true; Console.WriteLine("Finns INTE i Loggboken."); } break;

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av Nissan300zx:

@Thomas:
Tack=) nu ser jag att den söker igenom loopen.

Men problemet kvarstår.

När jag med hjälp av step in funktion kollar koden så ser jag att den på count i loggboken ändras till 2 när jag matar in två titlar.

Men i sökfunktionen så kommer jag inte åt de jag lagt in tidigare. Utan om programmet ska hitta titeln måste jag skriva in det senaste annars säger den hittade inte.

Hur löser jag det problemet? står verkligen helt tomt i huvudet. Jag har suttit flertals timmar med detta men fan koda är nog för svårt för mig.

om jag redan i case 2: lagt till Loggboken.add(post) borde inte detta spara alla loggar separat? istället så känns det som att den sparar loggarna men istället för att logga var för sig så skriver den över det föregående å sparar den +1. så jag får hela tiden nya counts men med samma text++.

case 3: Console.WriteLine("skriv in Titeln du vill söka på: "); string sök = Console.ReadLine(); bool hitta = false; for (int i = 0; i < Loggboken.Count; i++) if (sök == logg[i]) { hitta = true; Console.WriteLine("\nTitel: " +logg[0] +"\nInlägg: " + logg[1]); Console.WriteLine(); } else if (!hitta) { hitta = true; Console.WriteLine("Finns INTE i Loggboken."); } break;

Vart får du logg[i] ifrån? Du måste loopa den inre arrayen för varje entry.

Edit: Nu såg jag. Du kollar bara värdet i senaste loggen, din log variabel. Du måste nästa en till loop som går igenom LoggBook[i].Lenght för varje string[].
Tror det blir enklare att läsa med en foreach.

Kolla hur du löst case 1.

Trädvy Permalänk
Medlem
Registrerad
Jan 2013

@zaibuf:

Enligt min lärares kommentarer så ska jag lösa den med en for loop

Försök gärna lösa sökningen med endast EN for-loop också om du skulle ha tid. Då behöver du använda dig av indexering med [].

Trädvy Permalänk
Hedersmedlem
Plats
Uppsala
Registrerad
Jul 2001

@Nissan300zx Du använder fel variabel i if-satsen (sök == logg[i]). logg är det senaste du skrivit in (koden i case 2), därav problemet att den bara lyckas hitta den senaste.
Det är Loggboken[i] du vill använda. Det blir dock lite mer komplext eftersom Loggboken[i] är en array med två strängar i sig, så du måste kolla både Loggboken[i][0] (titeln) och Loggboken[i][1] (inlägg).

(Det finns klart snyggare lösningar än [0] och [1], men gissningsvis har ni inte kommit dit ännu, så kör vidare på det där. )

X370 Taichi / R7 1700 @ 3.75 GHz 1.2 V / 48 GB 3200 MHz CL14 / MSI GTX 1070 Gaming, OC / Samsung 960 EVO 500 GB / Corsair RM650x
LG G6 (H870)

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013
Skrivet av Nissan300zx:

@zaibuf:

Enligt min lärares kommentarer så ska jag lösa den med en for loop

Försök gärna lösa sökningen med endast EN for-loop också om du skulle ha tid. Då behöver du använda dig av indexering med [].

Det går väl att göra. Då loggBok[i] är en string[] så behöver du även iterera indexen i den för att få ut värdet.
Du kan göra det manuellt (i detta fall position 0 som jag antar är titeln) eller med en loop för att gå igenom alla värden.

I vanliga fall så arbetar man inte så här, så det är ingen fara om du tycker det är svårt. Man använder objekt med properties som representerar datan man arbetar med. Tycker det är lite fel av skolan att lära ut på detta sätt, men det verkar vara vanligt i gymnasiet då alla verkar få denna uppgift.

En loop som enbart söker igenom titlarna:

for(int i = 0; i < LoggBoken.Count; i++) { if(LoggBoken[i][0] == sök) { Console.WriteLine("Hittat!"); } }

Dold text

Två loopar som kommer att kolla texten i alla fält i string[]:

foreach(var log in Loggboken) { foreach(var item in log) { if(item == sök) { Console.WriteLine("Hittat!"); } } }

Dold text