2017-05-31 5 views
-2

Ich fühle mich irgendwie verloren, da wir das Lernen über Zeiger begann ich kippe irgendwie folgen und ich weiß, es ist wirklich wichtiges Thema in C.C-String rekursive Funktion von Gleichheit, um herauszufinden, Mitte

sowieso!

so bekam ich eine rekursive Funktion zu machen, die zwei Zeiger erhalten:

1) Zeiger auf Index [0].

2) Zeiger 2 in der Mitte der Zeichenfolge.

jetzt .. ich muss prüfen, ob der erste Teil von 0 bis Mitte von Mitte zu Ende gleich ist. wie ..... ADAMADAM.

bevor ich die Zeichenfolge übertrage, änderte ich ganze untere Buchstaben in Großbuchstaben, um Groß-/Kleinschreibung zu vermeiden ... also habe ich etwas wie dieses ... aber es weigerte sich zu arbeiten.

mit ebenfalls konstant ist verboten ...

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define TRUE 1 
#define FALSE 0 
#define SS 81 
int CheckString(char *,int *); 

int main() { 
    char str[SS]; 
    int length,len,strcheck; 
    printf("Please enter a string:\n"); 
    fgets(str,SS,stdin); 

    len=(strlen(str) - 1); 
    if((len>0)&&(str[len]=='\n')) // replacing '\n' key to '\0' 
     str[len]='\0'; 

    length=len/2; 
    strcheck=CheckString(str,&length); 
    if (strcheck==FALSE) 
     printf("FALSE.\n"); 
    else 
     printf("TRUE.\n"); 
    return 0; 
} 

// function 
int CheckString(char *str, int *i) { 
if (*str != '\0') 
    if (*str == str[*i]) 
     return CheckString(str+1,i++); 
    else 
     return FALSE; 
    return TRUE; 
} 

also denke ich, dass ich mit den Zeiger ein Problem bekam

+2

Warum haben Sie dies als 'C++' markiert? – PaulMcKenzie

+1

Warum übergeben Sie einen Zeiger auf 'int' zu' CheckString() '? Und 'i ++' ist wahrscheinlich nicht das, was du willst. –

+0

Hallo David, ty für Antwort ... das ist, was ich gefragt wurde ... von 2 Zeigern. – Alex

Antwort

1

Es scheint, dass Sie die folgende

#include <stdio.h> 
#include <string.h> 

int CheckString(const char *s, size_t *i) 
{ 
    return s[*i] == '\0' || *s == s[*i] && CheckString(s + 1, i); 
} 

int main(void) 
{ 
    char *s = "ADAMADAM"; 
    size_t i = strlen(s)/2; 

    int result = CheckString(s, &i); 
    printf("%s\n", result ? "true" : "false"); 

    return 0; 
} 

Die Programmausgabe bedeuten

true 

Anmerkung: Vielleicht sollten Sie den Wert für das zweite Argument berechnen die folgende Art und Weise

size_t i = (strlen(s) + 1)/2; 

darüber nachdenken.

+0

ye aber mit const chars ist auch verboten, ich sollte es erwähnen:/ – Alex

+1

@AlexBoyev Es wird eine falsche Funktion Erklärung, wenn das Qualifikationsmerkmal zu entfernen. Das ist die Funktion in diesem Fall möglicherweise nicht auf eine konstante Zeichenfolge angewendet werden. Sie können jedoch das Qualifikationsmerkmal entfernen, wenn Sie möchten. –

0

Die äußere Bedingung in der Schleife innerhalb CheckString() sollte für *(str + *i) != '\0' oder äquivalent für str[*i] != '\0' überprüfen. Außerdem müssen Sie nicht *i und sicherlich nicht i inkrementieren, da das ein Zeiger ist. Der Wert *i ist der Abstand zwischen den Zeichen, die in den zwei Hälften der Zeichenfolge überprüft werden.

könnte die modifizierte Funktion wie folgt aussehen:

int CheckString(char *str, int *i) { 
    if (str[*i] != '\0') { 
     if (*str == str[*i]) { 
      return CheckString(str+1,i); 
     } else { 
      return FALSE; 
     } 
    } 
    return TRUE; 
} 
+0

es funktioniert perfekt, nicht für Grenzpunkte testen ... aber könnten Sie erklären, wie kommt das 'i' bleibt gleich, ohne es zu fördern? – Alex

+0

Der Wert von '* i 'ist nur der Abstand von der Vorderseite der Zeichenfolge zur Mitte. Wenn Sie also 1 zu "str" ​​hinzufügen, zeigt "str + * i" auf das nächste Zeichen nach der Mitte und so weiter. –

+0

@ Alex-- Beachten Sie, dass aufgrund der Art, wie Sie die Mitte der Zeichenfolge berechnen, sowohl "ADAMADAM" als auch "MADAMADAM" TRUE zurückgeben. –

0

Das Problem Spezifikation sagt (mehr oder weniger):

Ich habe eine rekursive Funktion zu machen, bekam die 2 Zeiger erhalten:

  1. Zeiger 1 zum Index [0].
  2. Zeiger 2 in der Mitte der Zeichenfolge.

Ich muss überprüfen, ob der erste Teil von 0 bis Mitte gleich dem zweiten Teil von Mitte bis Ende ist, wie: ADAMADAM.

Als Übung in Rekursion ist das in Ordnung; Um die Funktionalität zu implementieren, ist die Rekursion übertrieben (Iteration ist in Ordnung).

Es gibt Verwirrung (Mehrdeutigkeit) über die Schnittstelle zu der Funktion - der Wortlaut der Frage scheint zwei char * Werte, aber der Code verwendet einen Zeiger auf eine ganze Zahl als zweites Argument. Das ist einzigartig. Ein ganzzahliger Wert könnte sinnvoll sein, ein Zeiger auf eine ganze Zahl jedoch nicht.

Wir müssen sorgfältig die Bedingungen definieren. Unter der gegebenen Beispielzeichenfolge (char str1[] = "ADAMADAM";) könnten die zwei Zeiger char *p1 = &str1[0]; char *p2 = &str1[0] + strlen(str1)/2; sein - was p1 Punkte zu dem ersten A und p2 zu dem dritten A bedeutet. Betrachten Sie einen alternativen String: char str2[] = "MADAMADAM";; Die äquivalente Formel würde p1 zeigt auf den ersten M und p2 zeigt auf der zweiten M verlassen.

Angenommen p1 und p2 im Gleichschritt erhöht werden, dann gilt:

  • Die Saiten unterschiedlich sind, wenn an irgendeinem Punkt vor *p2'\0' entspricht, *p1 != *p2.
  • Wenn *p2'\0' gleich, dann sind die Saiten gleich.
  • Per Definition p1 und p2 Punkt auf dem gleichen Array, so sind pointer Unterschiede legitim.
  • Ferner muss p1 weniger als p2 nützlich zu sein; p1 gleich p2 bedeutet, dass die Strings identisch trivial sind.
  • Es ist ein starkes Argument, dass die ‚Mitte der Zeichenkette‘ Kriterium bedeutet, dass entweder p2[p2 - p1] == '\0' oder p2[p2 - p1 + 1] == '\0' (für gerade und ungerade Saitenlängen beziehungsweise). Das heißt, der Abstand zwischen den beiden Zeigern gibt an, wo das Ende der Zeichenfolge sein muss. Das bedeutet, dass die Verwendung von p1 = &str[0] und p2 = &str[2] (auf einer der Beispielzeichenfolgen) fehlschlagen sollte, da das Ende der Zeichenfolge nicht an der richtigen Stelle ist. Und wenn die Zeichenfolge "AMAMAMAM" war, sollte die Verwendung von &str[0] und &str[2] fehlschlagen, weil das Ende der Zeichenfolge nicht an der richtigen Stelle ist; dito &str[0] und &str[6].
  • Dieses "starke Argument" ist jedoch auch eine Designentscheidung. Es wäre möglich, einfach zu verlangen, dass die Teilkette von p2 bis EOS (Ende der Kette) die gleiche ist wie die Kette von p1 für die gleiche Länge. In diesem Fall würde die Verwendung von &str[0] mit entweder &str[2] oder &str[6] (oder tatsächlich mit dem normalen &str[4]) auf "AMAMAMAM" gut funktionieren.

Die Verwendung einiger dieser Beobachtungen führt zu diesem Code. Wenn Sie wirklich unter der Anweisung sind, const nicht zu verwenden, entfernen Sie einfach die const Qualifier, wo sie erscheinen. Der Code funktioniert genauso.

#include <assert.h> 
#include <stdbool.h> 
#include <stdio.h> 
#include <string.h> 

static bool identical_halfstrings(const char *p1, const char *p2) 
{ 
    assert(p1 <= p2); 
    assert(strlen(p1) >= strlen(p2) + (p2 - p1)); 

    if (*p2 == '\0') 
     return true; 
    if (*p1 != *p2) 
     return false; 
    return identical_halfstrings(p1+1, p2+1); 
} 

int main(void) 
{ 
    const char *strings[] = 
    { 
     "ADAMADAM", 
     "MADAMADAM", 
     "nonsense", 
    }; 
    enum { NUM_STRINGS = sizeof(strings)/sizeof(strings[0]) }; 

    for (int i = 0; i < NUM_STRINGS; i++) 
    { 
     const char *p1 = strings[i]; 
     const char *p2 = strings[i] + strlen(strings[i])/2; 
     printf("[%s] ([%s]) = %s\n", p1, p2, 
       identical_halfstrings(p1, p2) ? "TRUE" : "FALSE"); 
    } 
    return 0; 
} 

Die zweite Behauptung stellt sicher, dass p1 und p2 auf demselben String verweisen -, dass es keine Null-Byte ist zwischen den Stellen, an von p1 spitz und p2.

Testfall Ausgabe:

[ADAMADAM] ([ADAM]) = TRUE 
[MADAMADAM] ([MADAM]) = TRUE 
[nonsense] ([ense]) = FALSE 

Nur für das Protokoll, eine iterative Version der gleichen Funktion ist:

static bool identical_halfstrings(const char *p1, const char *p2) 
{ 
    assert(p1 <= p2); 
    assert(strlen(p1) >= strlen(p2) + (p2 - p1)); 

    while (*p2 != '\0') 
    { 
     if (*p1++ != *p2++) 
      return false; 
    } 
    return true; 
} 

es die gleiche Ausgabe für die Beispieldaten erzeugt.