2016-04-24 7 views
1

(eine neuere Version meines Programms ist direkt am Ende)Vergleicht man zwei Arrays von ganzen Zahlen und Rückgabe des Index (C)

Ich brauche ein Programm mit einer Funktion zu erstellen, die zwei Arrays von ganzen Zahlen vergleichen und gibt die Index der ersten Stelle unterscheiden sie sich.

Ich muss einen Sentinel-Wert verwenden, um das Ende der gültigen Eingabe anstelle von EOF anzuzeigen, da eine Datei nicht zwei Dateiendungen haben kann.

Beispiel meiner Eingabe und Ausgabe für mein Programm gewünscht:

Eingang 1:

3 4 5 

    3 4 6 

Ausgang 1:

 2 

Erläuterung: Die dritten Werte von zwei Arrays verschieden sind, so druckt es den dritten Index (zählt als 0,1,2).

Ich schaute über ähnliche Probleme auf Stackoverflow. Viele Fehler wurden behoben und jetzt kann ich ein Programm kompilieren, ohne mir irgendwelche Fehler oder Warnungen zu geben. Aber es blendet mich, weil ich nicht verstehe, was genau nicht funktioniert.

Mein Problem, dass ich feststellen:

  • Wenn ich drücke Taste nach dem ersten Wert eingeben, stoppt das Programm zu arbeiten.

Ich nehme an, dass meine TableDiff-Funktion falsch ist, aber ich habe es aus den Notizen des Lehrers kopiert. Wenn ich keinen Tippfehler mache, sollte es keinen Unterschied geben.

Hier ist meine eingereichten Version:

/* 
* A simple program to sort numbers in the correct order        
*/ 

#include <stdio.h> 
#include <stdlib.h> 

#define MAX 10 //max elements in array 
#define SENTINEL -999 //indicate the end of valid input 

int main() { 
    int tableFill(int a[], int max); 
    int tableDiff (const int a[], const int b[], int n, int m); 
    void tablePrint (const int a[], const int b[], int n, int m); 

    int a[MAX]; 
    int b[MAX]; 
    int m,n,index; 

    m = tableFill(a, MAX); 
    n = tableFill(b, MAX); 

    tablePrint(a,b,n,m); 
    index = tableDiff(a,b,m,n); 

    if(index==-1) 
     printf("Index is the same"); 
    else 
     printf("Index is the different"); 

    return 0; 
} 

// read values from stdin into array up to 'max' values 
int tableFill(int a[], int max) { 

    int r;    // input from scanf 
    int next;   // next input value 
    int cnt = 0;  // count of values read 
    int *ptr;   //pointer 
    printf("Enter the numbers! \n"); 

    while ((r=scanf("%i", &next)) == 1 && next != SENTINEL) 
    { 
     if (r == 0) //invalid input data 
     { 
      printf("Nonnumeric data entered. Please enter a number. \n"); 
      while (getchar()!= '\n'); // flush invalid data 
     } 
     else 
      *ptr++=cnt; 
    } 

    if(r==1) //another value was read but the array is full 
     printf("Error - too many values. Array size %i.\n", max); 

    return ptr-a; //(ptrb - b) should return the same value 
} 

int tableDiff (const int a[], const int b[], int n, int m) 
{ 
    const int *ptra = a;  //start for 1st array 
    const int *ptrb = b;  //start for 2nd array 
    const int *endptra = a+m; //end for 1st array 
    const int *endptrb = b+n; //end for 2nd array 

    while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb) 
    { 
     ptra++; 
     ptrb++; 
    } 
    if(ptra==endptra && ptrb==endptrb) 
    { 
     return -1; 
    } 
    else 
     return ptra -a; //(ptrb - b) should return the same value 
} 

//print all elements in array. 
void tablePrint (const int a[], const int b[], int n, int m) 
{ 
    int i; //varriable to print 
    for (i = 0; i < n; i++) 
     printf ("%d ", a[i]); 
    printf ("\n"); 
} 

Hier ist meine neuere Version:

Das Programm setzt nun zu arbeiten, bis zweiten Sentinel erreicht (richtig funktioniert).

/* 
* A simple program to sort numbers in the correct order        
*/ 

#include <stdio.h> 

#define MAX 10 //max elements in array 
#define SENTINEL -999 //indicate the end of valid input 

int main() { 
    // read values from stdin into array up to 'max' values 
    int tableFill(int a[], int max); 
    //compare two arrays and returns the first subscript they differ 
    int tableDiff (const int a[], const int b[], int n, int m); 
    //print all elements in array 
    void tablePrint (const int a[], int n); 

    int a[MAX]; 
    int b[MAX]; 
    int m,n,index; 

    m = tableFill(a, MAX); 
    n = tableFill(b, MAX); 

    tablePrint(a,m); 
    tablePrint(b,n); 
    index = tableDiff(a,b,m,n); 

    if(index==-1) 
     printf("-1. Arrays are the same."); 
    else 
     printf ("\n The arrays differ at index '%d'.\n", index); 

    return 0; 
} 

// read values from stdin into array up to 'max' values 
int tableFill(int a[], int max) { 

    int r;    // input from scanf 
    int next;   // next input value 
    int cnt = 0;  // count of values read 
    int *ptr = a;  //pointer 
    printf("Enter the numbers! \n"); 

    while ((r=scanf("%i", &next))==0 || (next != SENTINEL)) 
    { 
     if (r == 0) //invalid input data 
     { 
      printf("Nonnumeric data entered. Please enter a number. \n"); 
      while (getchar()!= '\n'); // flush invalid data 
     } 
     else if (cnt == max) //another value was read but the array is full 
      printf("Error - too many values. Array size %i.\n", max); 
     else { 
      *ptr++ = next; 
      ++cnt; 
     } 
    } 

    return ptr-a; //(ptrb - b) should return the same value 
} 

//compare two arrays and returns the first subscript they differ 
int tableDiff (const int a[], const int b[], int n, int m) 
{ 
    const int *ptra = a;  //start for 1st array 
    const int *ptrb = b;  //start for 2nd array 
    const int *endptra = a+m; //end for 1st array 
    const int *endptrb = b+n; //end for 2nd array 

    while(ptra<endptra && ptrb<endptrb && *ptra==*ptrb) 
    { 
     ptra++; 
     ptrb++; 
    } 
    if(ptra==endptra && ptrb==endptrb) 
    { 
     return -1; 
    } 
    else 
     return ptra -a; //(ptrb - b) should return the same value 
} 

//print all elements in array 
void tablePrint (const int a[], int n) 
{ 
    int i; //loop counter 
    for (i = 0; i < n; i++) 
     printf ("%d ", a[i]); 
    printf ("\n"); 
} 
+1

'max! = SENTINEL' soll das' n! = SENTINEL' sein? – kaylum

+0

Ich habe keine Variable "n" in der Funktion tableFill, aber ich habe sie in ** next! = SENTINEL ** geändert. Es würde mehr Sinn machen, da ich den "nächsten" Wert für Sentinel überprüfen möchte. –

+1

Ja, tut mir leid, das war ein Tippfehler. Gemeint "nächstes" nicht "n". – kaylum

Antwort

1

Sie haben eine Reihe von Problemen in Ihrer Logik. Von denen die ersten in

while ((r=scanf("%i", &next)) == 1 && next != SENTINEL) 

verhindert, dass der Rest des Codes in der Schleife aus immer ist ein nicht-numerischer Wert eingegeben in dem Fall ausgeführt wird. Wenn r != 1, verlassen Sie die Schleife, nicht weiter darin verarbeiten.

Während kein Fehler, Funktionsprototypen innerhalb main funktioniert nur, wenn die Funktionen ausschließlich nicht aufeinander verlassen. Sie wissen nichts voneinander während der Ausführung. Besser, die Prototypen über main zu bewegen.

Der Rest Ihrer Logik war etwas schwierig zu folgen und übermäßig kompliziert. Wenn Sie nach einem Unterschied innerhalb von zwei Arrays suchen, müssen Sie nur über gemeinsame Elemente iterieren.Wenn sie eine unterschiedliche Anzahl von Elementen haben, wissen Sie, dass sie sich vom ersten eindeutigen Element unterscheiden. So können Sie Ihren Vergleichscode ein wenig reduzieren. So etwas wie die folgende ist in Ordnung:

/* check if array 'a' and 'b' are the same, else return index 
* of first difference, otherwise return -1 for equal arrays. 
*/ 
int tablediff (const int *a, const int *b, int sza, int szb) 
{ 
    int i, lim = sza < szb ? sza : szb; /* limit search to common elements */ 

    for (i = 0; i < lim; i++) /* for each common element check */ 
     if (a[i] != b[i]) 
      return i; 

    if (sza != szb)    /* if size differs, arrays differ */ 
     return lim; 

    return -1;     /* otherwise equal */ 
} 

Sie die Verwendung eines SENTINEL vermeiden kann nur durch geeignete Grenzen zu überprüfen. Während es Ihnen freisteht, eine arrayprint Funktion zu erstellen, die 2 Arrays druckt, ist es weit besser, eine Funktion zu erstellen, die ein einzelnes Array druckt und es zweimal aufruft.

Putting die Stücke zusammen, und unter Hinweis darauf, Sie nichts von stdlib.h verwenden, können Sie etwas Ähnliches wie die folgende tun könnte:

#include <stdio.h> 

#define MAX 10 //max elements in array 

int tablefill(int *a, int max); 
int tablediff (const int *a, const int *b, int sza, int szb); 
void tableprn (const int *a, int sza); 

int main (void) { 

    int a[MAX]; 
    int b[MAX]; 
    int idx, sza, szb; 

    sza = tablefill (a, MAX); 
    szb = tablefill (b, MAX); 

    tableprn (a, sza); 
    tableprn (b, szb); 

    if ((idx = tablediff (a, b, sza, szb)) == -1) 
     printf ("\n the arrays are the same.\n\n"); 
    else 
     printf ("\n the arrays differ at index '%d'\n\n", idx); 

    return 0; 
} 

/* read values from stdin into array up to 'max' values */ 
int tablefill (int *a, int max) 
{ 
    int idx = 0, tmp; 
    while (idx < max && scanf (" %d", &tmp) == 1) 
     a[idx++] = tmp; 

    return idx; 
} 

/* check if array 'a' and 'b' are the same, else return index 
* of first difference, otherwise return -1 for equal arrays. 
*/ 
int tablediff (const int *a, const int *b, int sza, int szb) 
{ 
    int i, lim = sza < szb ? sza : szb; 
    for (i = 0; i < lim; i++) 
     if (a[i] != b[i]) 
      return i; 

    if (sza != szb) 
     return lim; 

    return -1; 
} 

/* print all elements in array. */ 
void tableprn (const int *a, int sz) 
{ 
    int i; //varriable to print 
    for (i = 0; i < sz; i++) 
     printf (" %d", a[i]); 
    printf ("\n"); 
} 

Beispiel Equal Differ

$ /bin/arraycmp <../dat/20intsame.txt 
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495 
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495 

the arrays are the same. 

Beispiel

$ ./bin/arraycmp <../dat/20intdif.txt 
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1495 
8572 -2213 6434 16330 3034 12346 4855 16985 11250 1494 

the arrays differ at index '9' 

Prompts für Eingabe Providing

Wenn Benutzereingaben nehmen, ist es eine gute Idee, auch sinnvoll Aufforderungen zu beweisen, so dass der Benutzer an einem blinkenden Cursor nicht nach links schaut mich gefragt, ob das Programm gehangen hat, oder was es geht voran. Zusätzlich zur obigen Logik möchten Sie eine einfache Eingabeaufforderung hinzufügen, in der erläutert wird, was das Programm benötigt und wie die Eingabe bereitgestellt wird. Etwas einfach tun:

printf ("\nenter a max of 10 integers below 'ctrl+d` to end.\n"); 
    sza = tablefill (a, MAX); 
    printf ("enter a max of 10 integers below 'ctrl+d` to end.\n"); 
    szb = tablefill (b, MAX); 

    printf ("\nthe arrays entered are:\n\n"); 
    tableprn (a, sza); 
    tableprn (b, szb); 

(Anmerkung: ein manuelles EOF auf windoze zu erzeugen, die Tastenkombination ist ctrl + z)

Also für die Eingabe von weniger als 10 ganzen Zahlen für jeden Array Sie könnte etwas wie:

$ ./bin/arraycmp 

enter a max of 10 integers below 'ctrl+d` to end. 
10 12 14 16 17 
enter a max of 10 integers below 'ctrl+d` to end. 
10 12 14 15 17 

the arrays entered are: 

10 12 14 16 17 
10 12 14 15 17 

the arrays differ at index '3' 

Schauen Sie sich das Beispiel an und lassen Sie mich wissen, wenn Sie weitere Fragen haben.

+0

Meine C-Klassenlehrerin ist ziemlich alt und sie verwendet genau das gleiche Material, das sie vor Jahrzehnten gelehrt hat. So will sie Funktionsprototypen mit dem Haupt(), sonst Abzug Grad.Ich denke, es ergibt \t tablePrint (a, m); \t TabelleDruck (b, n); in Tabelle drucken mit 4 Variablen, weil es. Sonst gibt es mir einen Fehler. Nicht sicher über den Sentinel, die Aufgabe sagen mir, dies zu tun (die mit Diskette kommt). Ich denke, der Strukturcode ist für das moderne C sehr veraltet - aber das ist es, was mein Lehrer mir sagt. Die Logik ist jedoch mein persönliches Problem :-) Ich würde versuchen, es zu beheben. –

+1

Sie können alle Funktionen innerhalb von 'main' verschieben, solange sie nicht voneinander abhängen (oder Sie können sie unter' main' anordnen, so dass jede, die von einer anderen abhängig ist, zuerst deklariert wird.) Wenn sie so ist will es, dann bekommt sie es so. Wenn Sie weitere Fragen haben, lassen Sie es mich wissen, ich bin glücklich, weiter zu helfen. Wenn Sie ein 'SENTINEL' verwenden müssen, ist das auch in Ordnung, aber es kann Konflikte verursachen, wenn einer Ihrer Array-Werte '-999' ist. –

+0

Logik gefunden statt ** == 1 ** Ich setze **! = EOF ** zurück. Nun, wenn nicht numerische Daten eingegeben werden, sagt es so. –

Verwandte Themen