Список содержит метод возвращает false при использовании Math.sqrt () в качестве параметра - PullRequest
2 голосов
/ 14 июня 2019

Я освежаю свои знания в Java и работаю над упражнением из codewars. Проблема состоит в том, чтобы сравнить два массива, если элементы "одинаковы". Значение «то же самое» состоит в том, что элементы в «b» являются элементами в «a» в квадрате, независимо от порядка. Решение, которое я пытался сделать, это получить квадратный корень элемента в «b» и проверить, существует ли он в элементе «a», используя Math.sqrt (). Однако, когда я использую это как параметр для contains (), он всегда возвращает false.

Таким образом, чтобы проверить, действительно ли квадратный корень элемента 'b' существует в 'a', я попробовал простой if-else, чтобы проверить определенный элемент. Но когда я включаю его в Math.sqrt (), проблема возрастает.

Вот элементы множества a и b

int[] a = {121, 144, 19, 161, 19, 144, 19, 11};
int[] b = {121, 14641, 20736, 361, 25921, 361, 20736, 361};

что я преобразовал в список

List<Integer> setAList = Arrays.stream(setA)//int[] setA - parameter of a function
                                                    .boxed()
                                                    .collect(Collectors.toList());
List<Integer> setBList = Arrays.stream(setB)//int[] setB - parameter of a function
                                                    .boxed()
                                                    .collect(Collectors.toList());

Я преобразовал массив в список, чтобы воспользоваться методом contains (). Это мой код, когда я пытался проверить определенный элемент

double sqrd = Math.sqrt(setBList.get(6));
return setAList.get(5) == sqrd ? true : false;

И это дало ожидаемый результат - правда. Теперь вот код, когда я включил его в цикл for

boolean same = true;

for(int indexB : setB) {
    same = setAList.contains(Math.sqrt(indexB)) ? true : false; 
    System.out.println(Math.sqrt(indexB) + " " + same);

}

А вот и результат

11.0 false
121.0 false
144.0 false
19.0 false
161.0 false
19.0 false
144.0 false
19.0 false
false

Сначала я думал, что проблема может быть из-за типов данных, но я попытался привести значение типа double к int, но я все еще получаю тот же результат.

Ответы [ 3 ]

2 голосов
/ 14 июня 2019

Не прямой ответ, а обходной путь, позволяющий избежать подобных проблем:

Как объяснено в других ответах, ваша проблема является проблемой приведения, потому что вам приходится иметь дело со значениями double и int, и вам не придется сталкиваться с проблемами приведения.

Чтобы избежать этого, нужно возвести в квадрат значения в A вместо вычисления квадратных корней значений в B. Таким образом, вы когда-либо имели дело только с int values ​​

int[] a = {121, 144, 19, 161, 19, 144, 19, 11};
int[] b = {121, 14641, 20736, 361, 25921, 361, 20736, 361};

// Make a list containing the squares out of the b array
List<Integer> squares = Arrays.stream(b)
    .boxed()
    .collect(Collectors.toList());

// square all the values in B,
// and check that all the resultant values are present in the squares list
boolean same = Arrays.stream(a) // Stream<Integer> containing values in array a
    .map(i -> i* i) // Stream<Integer> containing values in array a squared
    .allMatch(squares::contains); // reduce to a boolean insuring that all values in the Stream<Integer> are present in the squares list

System.out.println(same);
1 голос
/ 14 июня 2019

setAList.get(5) == sqrd дает ожидаемый результат из-за расширяющегося примитивного преобразования из setAList.get(5) (то есть int) в double.

Если вы 'у вас есть setAList.contains(Math.sqrt(indexB)), вам нужно выполнить приведение вручную: setAList.contains((int)Math.sqrt(indexB)).

0 голосов
/ 14 июня 2019

Поиск точных значений с плавающей запятой, как это сделано в contains(), является плохой идеей в большинстве случаев из-за ограниченной точности значений с плавающей запятой;вы можете попробовать сами и посмотреть, для каких чисел Math.sqrt( number ) * Math.sqrt( number ) равно не так же, как number:

for (int i = 0; i < 100; i++) {
  final double r = Math.sqrt(i);
  final double s = r * r;
  if (s != i) {
    System.out.println(i + " != " + s);
  }
}

(выводит 51 неравный квадрат-корень из 100проверенные номера.)

...