Datum: 09.05.2008 12:21
Hallo Leute, ich muss folgenden Sache in Visual Basic schreiben. Ich habe insgesamt ca. 700 Namen, dabei sind es ca. 10 verschiednene Namen, die einfach unsoritier verteilt sind. Jetzt muss ich folgendes machen. Ich muss diese Namen in eine kleinere Tabelle zusammenfassen. So das in der Tabelle folgendes steht: Name1 kommt z.B. 100 mal vor, Name2 kommt 3 mal vor. Habt Ihr vielelciht Idee wie man sowas realiseren kann. Sitze schon die ganze Zeit und überlege mir wie man es machen kann! Die Namen werden aus einer Datenbank ausgelesen und werden nicht zwischengespeichert.
Datum: 09.05.2008 13:45
Du musst doch nur die Namen ablegen und dann Zeile für Zeile einfach nur gucken wie der name ist. Am besten machst du dir ein leeres Array (z.B. Namen(20), für die unterschiedlichen Namen) und fängst an zu scannen. Den Namen aus der ersten Zeile speicherst du in diesem Array. Dann suchst du in einer for-Schleife jede Zeile der Liste nach den Namen dem Array Namen() ab. Sollte der Name gefunden werden inkrementierst du den Namenszähler ansonsten packst du den Namen in das Array Namen() mit rein damit du einen weiteren namen hast. In C würde ich das in etwa so lösen:
#include <stdio.h> #include <string.h> typedef struct { char name[50]; int count; }name_struct; int main(){ char tab_names[][20] = {"Hannes","Tomas","Anna","Anna","Hannes","Hannes",0}; name_struct namen[20]={0,0}; int i,j; i=0; strcpy(namen[0].name, tab_names[0]); /* 1. Namen speichern */ while(tab_names[i][0] != 0){ /*Suchen bis Ende */ j = 0; while(1){ if(!strcmp(namen[j].name,tab_names[i])){ namen[j].count++; break; } j++; if(namen[j].name[0] == 0){ strcpy(namen[j].name, tab_names[i]); namen[j].count++; break; } } i++; } i=0; /* Ausgabe */ while(namen[i].name[0] != 0){ printf("%s: %d\n",namen[i].name,namen[i].count); i++; } return 0; } |
In VB ist das natürlich noch etwas einfacher, aber ich habe beim Jahrelangen C-Programmieren irgendwie das meiste aus VB Zeiten vergessen.
Datum: 09.05.2008 14:07
Eine einfache Methode ist das Array mit den Namen erst zu sortieren und dann durchzuzählen. Das benötigt je nach Umsetzung sehr wenig Speicherplatz und kann schön modularisiert werden. Wenn die Option besteht würde ich die Liste direkt beim Auslesen aus der Datenbank sortiert anfordern (ORDER BY name). Dann könnte man aber auch direkt das Durchzählen dabei erledigen (GROUP BY name) ;)
Datum: 09.05.2008 14:13
Wie Kai schon schreibt. 1. Sortieren 2. in einer Schleife gucken ob der nächste Name Identisch ist. Wenn ja Zähler plus eins, andernfalls ab der Position wieder von vorne. So wird die Liste nur einmal durchlaufen, schneller und simpler gehts eigentlich nicht.
Datum: 09.05.2008 14:14
Könnte diese "Datenbank" evtl. eine Excel-Liste sein? Dann gibt es die Funktion "Zählewenn". Für 10 verschiedene Namen ist das die einfachste und schnellste Möglichkeit. Falls es keine Excel-Tabelle ist, könnte man die Datenbank evtl. nach CVS (oder CSV?) konvertieren, in Excel importieren und die 3 Formeln in eine Zelle tippen.
Datum: 09.05.2008 14:16
Naja, am einfachsten wäre es, das Zählen direkt per "SELECT COUNT..." in
der DB-Abfrage zu erledigen. Aber VB ist natürlich etwas kniffliger.
Kennt Visual Basic Hash-Tabellen? Damit wäre es einfach. Alternativ
kannst du die Tabelle selbst implementieren, ist aber etwas
komplizierter. Dazu kenne ich Visual Basic auch zu wenig.
Ach ja, Hash-Tabellen werden in einigen Programmiersprachen nicht
explizit so bezeichnet. Man kann dann einfach Arrays mit beliebigen
Werten indizieren. Z.B. in Javascript (ungetestet):
function count() {
var counts = [];
var i;
var name;
for (i in names) counts[names[i]]++;
}
virtuPIC
/ggadgets for tools & toys
Datum: 09.05.2008 14:19
In vielen Programmiersprachen gibt es so gegannte assoziative Arrays. Das sind Arrays, die nicht über nur über eine fortlaufenden Ganzzahl, sondern über einen (fast) beliebigen Datentyp adressiert werden können. In C++ heißen sie Maps, in Python Dictionaries und in Lisp Association Lists. VB kenne ich nicht, aber ich kann mir gute vorstellen, dass es dort ebenfalls so etwas gibt. Wenn ja, legst du ein assoziatives Array mit den Anzahlen der einzelnen Namen an, das über die Namen adressiert wird. In Python würde das etwas so aussehen:
count = {} # Leeres Dictionary anlegen
while True:
name = raw_input() # Eingabe eines Namens
if name == "": # Eine Leerzeile beendet die Eingabe
break
try:
count[name] += 1 # Zähler für den Namen eins erhöhen
except KeyError: # Wenn der Name zum ersten Mal auftritt
count[name] = 1 # Zähler auf eins setzen
for name, cnt in count.items(): # Inhalt des Dictionarys als Liste
print name, cnt # von Namen und Anzahlen ausgeben
|
Falls es diese assoziativen Arrays nicht gibt, kannst du eine Liste (oder ein erweiterbares normales Array) anlegen, deren Elemente Paare aus Name und Anzahl sind. Eine Scuhfunktion nach dem Namen führt zum richtigen Element, dessen Anzahlwert anschließend erhöht wird. Wird ein Name nicht gefunden, wird eine neues Element an das Ende der Liste angehängt.
Datum: 09.05.2008 14:24
Habe gerade gegoogelt: In VB scheinen die Dinger "Collections" zu heißen.
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos verwenden, Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel