Permalänk

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;

Permalänk
Hedersmedlem

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.

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

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.

Permalänk
Medlem

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.

Permalänk

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");

}

Permalänk
Avstängd
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");

Permalänk
Medlem
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) { ... }

Permalänk
Medlem
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())

Permalänk
Avstängd
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.

Permalänk
Medlem
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

Permalänk
Medlem
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"

Permalänk

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.

Permalänk
Medlem
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.

Visa signatur

Outtröttlig, löpartokig besserwisser!

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

Permalänk

@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]

Permalänk
Medlem

@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.

Visa signatur

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

Permalänk
Medlem
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.

Permalänk
Medlem

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!

Visa signatur

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

Permalänk
Avstängd

@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.

Permalänk
Medlem

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.

Visa signatur

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

Permalänk

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; } } } } }

Permalänk
Hedersmedlem

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.)

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem

@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.

Permalänk

@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;

Permalänk
Medlem
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.

Permalänk

@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 [].

Permalänk
Hedersmedlem

@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. )

Visa signatur

Asus ROG STRIX B550-F / Ryzen 5800X3D / 48 GB 3200 MHz CL14 / Asus TUF 3080 OC / WD SN850 1 TB, Kingston NV1 2 TB + NAS / Corsair RM650x V3 / Acer XB271HU (1440p165) / LG C1 55"
Mobil: Moto G200

Permalänk
Medlem
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