Frage

habe ich diesen Suchalgorithmus für eine geordnete Array von ganzen Zahlen implementiert. Es funktioniert gut für die erste Datensatz ich es füttern (500 ganze Zahlen), aber nicht auf mehr sucht. Doch alle Sätze arbeiten perfekt mit den anderen vier Suchalgorithmen I für die Zuordnung implementiert haben.

Dies ist die Funktion, dass die Rendite einer seg Fehler auf der Leitung 178 (aufgrund eines unerwarteten negativen m-Wert). Jede Hilfe wäre sehr geschätzt.

CODE:

155 /* perform Algortihm 'InterPolationSearch' on the set
156  * and if 'key' is found in the set return it's index
157  * otherwise return -1 */
158 int
159 interpolation_search(int *set, int len, int key)
160 {
161   int l = 0;
162   int r = len - 1;
163   int m;
164
165   while (set[l] < key &&  set[r] >= key)
166   {
167
168     printf ("m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l])\n");
169
170     printf ("m = %d + ((%d - %d) * (%d - %d)) / (%d - %d);\n", l, key, set[l], r, l, set[r], set[l]);
171     m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l]);
172     printf ("m = %d\n", m);
173
174 #ifdef COUNT_COMPARES
175     g_compares++;
176 #endif
177
178     if (set[m] < key)
179       l = m + 1;
180     else if (set[m] > key)
181       r = m - 1;
182     else
183       return m;
184   }
185
186   if (set[l] == key)
187     return l;
188   else
189     return -1;
190 }

OUTPUT:

m = l + ((key - set[l]) * (r - l)) / (set[r] - set[l])
m = 0 + ((68816 - 0) * (100000 - 0)) / (114836 - 0);
m = -14876

Danke!

Rhys

War es hilfreich?

Lösung

Das ist, weil der Zwischenwert des calcualtion (68816 - 0) * (100000 - 0) den Wert übersteigt, der innerhalb eines int gehalten werden kann. Sie können den Zwischenwert auf einen Datentyp gegossen, die die größere Zahl (zum Beispiel eines long long) halten können, um das Problem zu lösen

Andere Tipps

68816 * 100000 mehr als 2 ^ 31, was sehr wahrscheinlich ist die Grenze Ihrer Maschine int Datentypen. Sie erleben Integer-Überlauf.

Wenn Ihr Compiler unterstützt, versucht Wechsel zu long long. Sie können, indem Sie überprüfen

#include <stdlib.h>
printf("the long long type is %u bits", (unsigned int) (CHAR_BIT * sizeof (long long)));

Wie Naveen wies darauf hin, werden Sie auch sicher, dass die tatsächlichen Berechnungen vornehmen müssen in dieser Präzision hergestellt werden. Dies kann durch Gießen erfolgen.

Ihre Arithmetik ist wahrscheinlich die Größe von int auf Ihrer Plattform überfüllt.

Sie müssen eine von zwei Dinge zu tun. Verwenden Sie entweder einen größeren Integer-Typen (falls vorhanden) oder Neufassung Ihre Berechnung, so dass Sie nicht einen so großen Zwischenwert zu schaffen brauchen.

m = 0 + ((68816 - 0) * (100000 - 0)) / (114836 - 0);

68816 * 100000 = 6881600000 = (binary)110011010001011001110001000000000

Das ist, 33 Bits. Auf nahezu allen Plattformen int sind 32 Bits oder (in selteneren Fällen) 16 Bit.

Sie können mit long long versuchen, die garantiert mindestens 64 Bit (hinzugefügt in C99, aber die meisten Compiler es in C90 unterstützt auch).

Sie müssen vorsichtig von Integer-Überlauf sein. Es wäre besser, die Berechnung von m als Typ als int größer auszuführen, und dann zurück zu int werfen, wenn Sie fertig sind.

Darüber hinaus können Sie müssen vorsichtig sein, wenn Ihr Satz Duplikate enthält, wie Sie eine Division durch Null-Fehler auf der gleichen Linie erhalten können (das heißt, wenn set[r] == set[l]).

Um Probleme wie Datenüberlauf zu vermeiden, können Sie zusätzlich eine große Zahl Bibliothek verwenden. Ein gutes Beispiel ist: http://gmplib.org/ . Natürlich wird es ein wenig mehr Aufwand, aber die Gesamtleistung ist sehr gut hinzufügen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top