Hallo Jessi,
@Semjon Michailowitsch:
…
Aber falls du meinen ersten Eintrag richtig gelesen hättest,
hättest du bemerkt, dass ich gar keine fertige Lösung erwartet
hatte, sondern vielmehr Ansätze die mir dabei hätten helfen
können das alle zu verstehen. Denn hätte ich irgendetwas für
mich verständliches in Büchern oder anderen Internetseiten
gefunden, dann hätte ich doch hier nicht um Hilfe gebeten.
OK, so betrachtet war meine (offen und ehrlich gemeinte)
Antwort vielleicht etwas überzogen. Vielleicht kann ich,
im Sinne Deiner Anfrage, denn doch noch etwas hilfreiches
beitragen.
Zwar hat softwareschmied schon eine fertige Lösung angeboten,
diese ist aber imho nicht optimal auf das Problem zugeschnitten.
Deine Problemstellung sieht sehr nach DNA-Basen aus. Insofern
wären folgende Schritte zu machen:
-
Stringlängen gleich/ungleich in etwa so:
int l1 = strlen(argv[1]), l2 = strlen(argv[2]);
…
if(l1 != l2) {
… Fehler
}
was der Konvention entspricht, daß die main()-Funktion
(der Eintrittspunkt des Programms in C) folgende Signatur
hat:
int main(int argc, char \*argv[])
wobei argc die Anzahl der „Worte“ auf der Kommandozeile
und argv[] das Feld mit den Inhalten ist. Daher stehen
die Strings in argv[1] bzw. argv[2] (in argv[0] steht
der Programmname selbst => siehe softwareschmieds Lösung).
-
Der nächste Schritt bestünde imho darin, die Strings
in einen Puffer (sall) der Länge l1+l2 zu kopieren, um
diese besser behandeln zu können:
char *sall = malloc(l1 + l2 + 2);
char *s1 = strcpy(sall, argv[1]);
char *s2 = strcpy(sall+l1, argv[2]);
-
Da es sich um DNA-Basen handelt, können wir alle
in Großbuchstaben umwandeln, um leichter vergleichen
zu können:
char *p = sall;
do *p &= ~0x20; while(*p++); /* make all chars lower case */
Die Umwandlung von Groß- zu Kleinbuchstaben bei ASCI besteht
im Ausblenden eines Bits in der Binärdarstellung (Bit 6).
Welches Bit das ist, siehst Du, wenn Du im Windows-
taschenrechner aus „wissenschaftliche Ansicht“ umstellst,
die Zahl 32 (20hex) eingibst und dann unter der Anzeige
auf (*)Bin klickst.
-
Hast Du reine Großbuchstaben, besteht die Berechnung der
Hamming-Distanz nur noch aus einem XOR der Buchstaben
an den entsprechenden Stellen in den Strings. Liefert
das XOR einen Wert, sind die Buchstaben unterschiedlich
(hd = hd + 1), ansonsten bleibt sie gleich:
const char *s = sall;
const char *p = s + (l1+l2)/2;
dist = 0;
do dist += !!(*s++^*p++); while(*p)
Dieses !! vor der runden Klammer ist die doppelte Negation,
sie bedeutet: wenn (0), dann 0; wenn (nicht 0) dann 1
(ein übliches Idiom).
-
Ach ja, bleibt nur noch die Feststellung, ob nur
„erlaubte“ Buchstaben vorkommen. Um das genau dann
zu Lösen, wenn die Menge der vorkommenden Buch-
staben „überschaubar“ ist, benutzt man eine sog.
lookup table (Nachschlagetabelle), in der
man die Stellen für alle nicht erlaubten Buchstaben
mit „1“ und die der erlaubten Buchstaben mit „0“
belegt. Dann addiert man nur noch über alle Zeichen
im String: summe = summe + lookup_table[charachter]
Wenn die Summe 0 bleibt, warennur erlaubte Zeichen im
String, ein unerlaubtes Zeichen führt zu „nicht 0“,
also zu einem Fehler:
const char* erlaubt = „AaTtCcGg“;
const char* s = sall;
int sum = 0;
unsigned char lut[256];
memset(lut, 1, sizeof(lut));
do lut[*erlaubt] = 0; while(*erlaubt++);
do sum += lut[*s]; while(*s++);
// if sum !=0 dann => Fehler
Aus diesen Betrachtungen könnte man ein Programm entwerfen,
das auch DNA-Strings sehr großer Länge in kurzer Zeit
verarbeitet und das Resultat ausgibt.
Naja, hoffentlich habe ich nicht mehr Verwirrung
als Nutzen gestiftet
Grüße
CMБ