Z ciekawości spróbowałem to sobie rozwiązać w javascripcie - tu masz moje rozwiązanie, załatwiające problem floatów (myślę, że nie będzie problemu z przetłumaczeniem tego na c++):
Kopiuj
// funkcja pomocnicza - oblicza maksymalną liczbę miejsc po przecinku
// w podanych danych wejściowych (tablica)
function getMaxDecimals(tab) {
var splitedFloat, currentDecimals, maxDecimals = 0;
for(var i = 0; i < tab.length; i++) {
// zamiana float na string i podzielenie na dwie części wg separatora dziesiętnego
splitedFloat = tab[i].toString().split('.');
// pobranie długości "części dziesiętnej" stringa
currentDecimals = splitedFloat[1] != undefined ? splitedFloat[1].length : 0;
// sprawdzenie czy bieżąca wartość jest większa od wartości maksymalnej i ewentualna podmianka
maxDecimals = currentDecimals > maxDecimals ? currentDecimals : maxDecimals;
}
return maxDecimals;
}
// główna funkcja - zwraca true jeśli z podanych inputów da się ułożyć ciąg arytmetyczny
// lub false jeśli się nie da
function checkIfAritmetic(tab){
var i, r;
// obliczenie mnożnika - czyli 10 do potęgi n,
// gdzie n to maksymalna liczba miejsc po przecinku
multiplier = Math.pow(10, getMaxDecimals(tab));
// pozbycie się floatów przez pomnożenie przez mnożnik i zmiane typu na int
for(i = 0; i < tab.length; i++) {
tab[i] = parseInt(tab[i] * multiplier);
}
// posortowanie tablicy
tab.sort(function(a, b){return a-b});
// no i tu już prosto - podobnie jak u Ciebie
r = tab[1] - tab[0];
for(i = 2; i < tab.length; i++) {
if((tab[i - 1] + r) != tab[i]) {
return false;
}
}
return true;
}
// testy
var input;
console.log('\nTESTY:\n\n');
console.log('test1: [0, 1, 2, 3, -1] zwraca true');
input = [0, 1, -1];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');
console.log('test2: [0.0000000000000001, 1, -1] zwraca false');
input = [0.0000000000000001, 1, -1];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');
console.log('test3: [0, -0.3, 0.6, 0.9, 0.3] zwraca true');
input = [0, -0.3, 0.6, 0.9, 0.3];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');
console.log('test4: [0, -0.3, 0.6, 0.8999999999999999, 0.3] zwraca false');
input = [0, -0.3, 0.6, 0.8999999999999999, 0.3];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');
console.log('test5: [0.0, 0.6, 1.2, 1.8] zwraca true');
input = [0.0, 0.6, 1.2, 1.8];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');
console.log('test6: [0.0, 0.6, 1.2, 1.7999999999999998] zwraca false');
input = [0.0, 0.6, 1.2, 1.7999999999999998];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');
W wersji zwykłej nie udało mi się tak dobrać epsilona, żeby testy przeszły (chyba, że mam jakiś błąd):
Kopiuj
function checkIfAritmetic(tab){
var i, r, epsilon;
epsilon = 0.0000000000000000;
tab = tab.sort(function(a, b){return a-b});
r = tab[1] - tab[0];
for(i = 2; i < tab.length; i++) {
if(Math.abs((tab[i - 1] + r) - tab[i]) > epsilon) {
return false;
}
}
return true;
}