Permalänk

[c++] linjär sökning

Hej
Jag behöver litte hjälp med programmering uppgift. Jag kan inte skriva sök funktion.Kan ni hjälpa mig ?

#include <iostream> #include <vector> #include <limits> //För att använda numeric_limits using namespace std; class Film { public: // Deklarerar variablerna för de data som behövs string Titel; string Media; // Denna funktion skriver ut filmen på skärmen void skrivFilm() { cout << endl; cout << "Titel: " << Titel << endl; // Skriver ut filmens titel cout << "Media: " << Media << endl; // Skriver ut filmens media } }; int main() { setlocale(LC_ALL, "swedish"); // Denna funktion låter mig använda svenska vector<Film> Arkiv; // Skapa en vector av typen Film char menyVal; // Denna variabel håller reda på vilket val användaren anger i huvudmenyn Film nyFilm; // För att skapa en film behöver vi ett objekt att spara den i do { system("cls"); // Se till att rensa skärmen cout << " ** ARKIV ** " << endl; cout << "*******************" << endl; cout << "1: Ny film" << endl; cout << "2: Sök efter film" << endl; cout << "3: Visa alla" << endl; cout << "0: Avsluta" << endl; cout << "___________________" << endl; cout << "Ange val: "; cin >> menyVal; cin.ignore( numeric_limits <streamsize>::max(), '\n' ); switch(menyVal) { case '1': { system("cls"); cout << "\n\n1: Ny film"; cout << endl << endl; // Vi ger objektets titel-variabel ett värde cout << "Ange filmens Titel: "; getline(cin, nyFilm.Titel); cout << endl; // Vi ger objektets media-variabel ett värde cout << "Ange filmens Media: "; getline(cin, nyFilm.Media); cout << endl; // Vi lägger vårt filmobjekt i vektorn Arkiv.push_back( nyFilm ); break; // Undvik fall-through } case '2': { // // sök funktion break; } case '3': { system("cls"); for(int i=0; i<Arkiv.size(); i++) // Räkna upp alla filmer i Arkiv { Arkiv[i].skrivFilm(); // Skriv ut dem med hjälp av funktionen skrivFilm(); } cout << "\n\nTryck på ENTER för Huvudmeny."; cin.ignore(); break; } case '0': { break; } default : cout << "Felaktigt val, försök igen." << endl; system("cls"); } } while( menyVal != '0'); }

Permalänk
Medlem

Kolla först hur många värden du har i din vector, sen släng in vectorn i en for loop där du loopar igenom alla element
Lägg också till ett true/false statement så att du kan hoppa ur loopen

t.ex.

i < antalElement && !found

För varje loop, jämför du elementet med värdet du letar efter
När du hittat ditt element så ändra bara din bool variabel och loopen bör hoppa ur och du har ditt värde

Permalänk
Medlem

Finns alltid mängder med sätt, några andra kan vara följande:
find
fint_if
lambdas

Inget du kanske behöver gå in på i detta läget, men är du intresserad så kan du ju ta en google.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk

jag är riktig nybörjare , jag har ingen aning hur ska jag börja. Det vore superbra om ni kudde ge min ett exempel eller enklare instruktionen. Tack på förhand

Permalänk
Datavetare

Här har du ett exempel på hur man kan söka bland personer som i detta fall har två egenskaper, namn och ålder. Har använt en del C++11 finesser, men om du kör på g++/clang++/VC++ av nyare snitt så ska det inte vara något problem alls. Själv körde jag med g++4.7

#include <algorithm> #include <iostream> #include <vector> using namespace std; struct person { const string name; const int age; person(string name_, int age_) : name(name_), age(age_) { } }; struct by_name { const string name; by_name(string name_) : name(name_) { } bool operator()(person p) { return p.name == name; } }; struct by_age { const int age; by_age(int age_) : age(age_) { } bool operator()(person p) { return p.age == age; } }; int main() { vector<person> names{ person("Adam", 42), person("Bertil", 17), person("Cesar", 13), person("David", 50) }; auto p1 = find_if(begin(names), end(names), by_age(17)); if (p1 != end(names)) cout << "Found someone with age 17: " << p1->name << endl; else cout << "No one with that age" << endl; auto p2 = find_if(begin(names), end(names), by_name("David")); if (p2 != end(names)) cout << "Has age: " << p2->age << endl; else cout << "No one with that name" << endl; }

Dold text

Edit: lite bättre förklaring kanske är på sin plats...

Jag använder "find_if" som redan föreslagits i tråden. Den hittar du i <algorithm>. Den tar en startpunkt (jag använder början på min vektor), en slutpunkt (slutet på min vektor) samt något som kan behandlas som en funktion med argument "person" och returnerar true/false.

Det sista löser jag med två hjälpklasser, en för att söka på namn och en för att söka på ålder (man kan göra detta med lambda men tycker koden blir relativt oläslig, blir lite mindre att skriva). För att kunna behandla ett objekt som en funktion i C++ så måste man överlagra operator() vilket är den enda metod dessa klasser har.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

Här finns några olika algoritmer för att göra en linjär sökning.

http://en.wikipedia.org/wiki/Linear_search#Pseudocode

De är alla skrivna i pseudokod (blanding av engelska och kod) så du får välja den du tycker att du förstår bäst och skriva om det i C++

Permalänk
Hedersmedlem
Skrivet av Yoshman:

Det sista löser jag med två hjälpklasser, en för att söka på namn och en för att söka på ålder (man kan göra detta med lambda men tycker koden blir relativt oläslig, blir lite mindre att skriva).

I det där fallet blir det väl inte så ohemult oläsligt förutsatt att man har vant sig vid hur lambdafunktioner ser ut (och det är det ju väl investerad tid; man kan väl gissa att bruket av sådana ändå kommer att öka med tiden)?

Permalänk
Datavetare
Skrivet av Elgot:

I det där fallet blir det väl inte så ohemult oläsligt förutsatt att man har vant sig vid hur lambdafunktioner ser ut (och det är det ju väl investerad tid; man kan väl gissa att bruket av sådana ändå kommer att öka med tiden)?

Säger inte vad som är rätt/fel här. Personligen är jag av åsikten att då kod som faktiskt används typiskt skrivs en gång och läsas massor med gånger så är det ens förbannade skyldighet som professionell utvecklare att skriva det som är lättast att förstå, inte det som sparar några sekunder när man skriver koden.

Vilket är lättast att förstå?

find_if(begin(names), end(names), by_name("David"))

find_if(begin(names), end(names), [](person p){ return p.name == "David"; });

Den första kräver mer kod då jag måste skriva hjälpklassen, men varje gång jag använder den så blir det mindre kod.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Hedersmedlem
Skrivet av Yoshman:

Säger inte vad som är rätt/fel här. Personligen är jag av åsikten att då kod som faktiskt används typiskt skrivs en gång och läsas massor med gånger så är det ens förbannade skyldighet som professionell utvecklare att skriva det som är lättast att förstå, inte det som sparar några sekunder när man skriver koden.

Jag håller naturligtvis med när det gäller mera komplexa funktioner men i triviala fall som det där, när man knappt kan hävda att funktionen är en rad lång, tycker jag inte att läsligheten blir så mycket sämre (dessutom ser man ju direkt vad anropet till find_if gör).

Permalänk

hej igen
jag får inte använda (find_if). Jag måste ha n enkel for-sats eller while-sats som stegar igenom vektorn tills sökta elementet hittas eller tills man nått slutet av vektorn.

Permalänk
Hedersmedlem
Skrivet av migorambo:

hej igen
jag får inte använda (find_if). Jag måste ha n enkel for-sats eller while-sats som stegar igenom vektorn tills sökta elementet hittas eller tills man nått slutet av vektorn.

Var uppstår problemen? Du gör ju redan hälften i "visa alla"; du behöver bara fråga efter vad man vill söka efter och jämföra istället för att skriva ut.

Permalänk
Medlem
Skrivet av migorambo:

hej igen
jag får inte använda (find_if). Jag måste ha n enkel for-sats eller while-sats som stegar igenom vektorn tills sökta elementet hittas eller tills man nått slutet av vektorn.

ska du använda dig av en for-sats så har du 3 olika vettiga alternativ (i alla fall de jag kommer på nu)

vector<int> test_vector; for(int i=0; i<test_vector.size(); i++) { cout << test_vector[i]; // utan felhantering cout << test_vector.at(i); //med felhantering } vector<int>::const_iterator it; for(it=test_vector.cbegin(); it!=test_vector.cend(); ++it) { cout << *it; } for(int& i: test_vector) //funkar bara med c++11 { cout << i; }

välj någon av dom och gör helt enkelt en jämförelse av varje film med värdet du letar efter. tex

if(Arkiv[i].title == sökord) //rätt film;

Permalänk
Medlem

int linearSearch(int arr[], int size, int value) { bool found = false; int index = -1; for (int i = 0; i < size && !found; i++) { if(arr[i] == value) { found = true; index = i; } } return index; }

Gör om till vector så ska det fungera

Visa signatur

Main dator: i5 750 4Ghz, GTX 770 4GB, Intel SSD 80GB, 8GB Ram
Servern: Core 2 Duo, 4GB Ram, 4x2TB Lagring, Ubuntu Server 12.04

Permalänk
Datavetare

Använder man hjälp-klasserna by_name och by_age från mitt exempel ovan kan man skriva även söka så här med en "for-each" (C++11) och utan "find_if".

vector<person> persons{ person("Adam", 42), person("Bertil", 17), person("Cesar", 13), person("David", 50) }; by_age match_age(13); for (person p: persons) if (match_age(p)) cout << "Found person with specificed age: " << p.name << endl; by_name match_name("Adam"); for (person p: persons) if (match_name(p)) cout << "Found person with specificed name: " << p.age << endl;

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk

jag har försökt många gånger men utan resultat

Permalänk
Hedersmedlem
Skrivet av migorambo:

jag har försökt många gånger men utan resultat

Hur långt har du kommit? Vad går fel?

Permalänk

#include <iostream> #include <vector> #include <algorithm> using namespace std; class Film { public: // Deklarerar variablerna för de data som behövs string Titel; string Media; // Denna funktion skriver ut filmen på skärmen void skrivFilm() { cout << endl; cout << "Titel: " << Titel << endl; // Skriver ut filmens titel cout << "Media: " << Media << endl; // Skriver ut filmens media } }; int main() { vector<Film> Arkiv; // Skapa en vector av typen Film char menyVal; // Denna variabel håller reda på vilket val användaren anger i huvudmenyn Film nyFilm; // För att skapa en film behöver vi ett objekt att spara den i do { cout << " ** ARKIV ** " << endl; cout << "*******************" << endl; cout << "1: Ny film" << endl; cout << "2: Sök efter film" << endl; cout << "3: Visa alla" << endl; cout << "0: Avsluta" << endl; cout << "___________________" << endl; cout << "Ange val: "; cin >> menyVal; cin.ignore( numeric_limits <streamsize>::max(), '\n' ); switch(menyVal) { case '1': { cout << "\n\n1: Ny film"; cout << endl << endl; // Vi ger objektets titel-variabel ett värde cout << "Ange filmens Titel: "; getline(cin, nyFilm.Titel); cout << endl; // Vi ger objektets media-variabel ett värde cout << "Ange filmens Media: "; getline(cin, nyFilm.Media); cout << endl; // Vi lägger vårt filmobjekt i vektorn Arkiv.push_back( nyFilm ); break; // Undvik fall-through } case '2': { vector<int> Film; for(int i=0; i<Film.size(); i++) { cout << Film[i]; // utan felhantering { if(Arkiv[i].Titel == titel); break; } case '3': { system("cls"); for(int i=0; i<Arkiv.size(); i++) // Räkna upp alla filmer i Arkiv { Arkiv[i].skrivFilm(); // Skriv ut dem med hjälp av funktionen skrivFilm(); } cout << "\n\nTryck på ENTER för Huvudmeny."; cin.ignore(); break; } case '0': { break; } default : cout << "Felaktigt val, försök igen." << endl; system("cls"); } } while( menyVal != '0'); };

Permalänk
Medlem

Vet inte hur pass mycket tid du har lagt ner på detta?

Var lagrar du alla dina filmer, jo i din vector Arkiv.
Det är alltså den du måste på nåt sätt loopa igenom och inte en ny vector.

Byt ut vectorn och fixa din loop och if-sats så borde det gå bättre.

Visa koden om du fortfarande stöter på problem.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770