Dla studentów JavaRush wyzwania programistyczne, Java i walidator są najlepszymi przyjaciółmi. Jednak dla każdego padawana programisty przychodzi taki moment, kiedy trzeba czasem zejść z utartych szlaków, wymyślić dla siebie miniprojekty i przygotować się do rozmów kwalifikacyjnych. Wydaje się, że na rozmowie kwalifikacyjnej powinieneś spotkać się z dokładnie tymi samymi praktycznymi problemami związanymi z Javą, co na kursie. W większości przypadków jest to prawdą, ale niektóre firmy lubią zadawać podchwytliwe pytania lub robić coś niezwykłego. Aby uniknąć dezorientacji podczas stresującej rozmowy kwalifikacyjnej, warto spróbować samodzielnie rozwiązać takie problemy z Java w domu.
W tym artykule przyjrzymy się pół tuzinu tych trudnych zadań. Zalecamy najpierw przeczytać warunek i spróbować rozwiązać go samodzielnie. I jeszcze jedno: nie zapomnij o codziennym rozwiązywaniu problemów Java z kursu!
- Zadanie 1: Tworzenie od podstaw nieskończonej pętli
- Zadanie-2. Utwórz komentarz, który zostanie wykonany
- Zadanie 3: Utwórz nazwaną pętlę
- Zadanie-4. O pojedynczym duplikacie w tablicy liczb całkowitych
- Zadanie-5. O nieunikalnym duplikacie w tablicy liczb całkowitych
Problem Java - 1: Tworzenie od zera nieskończonej pętli
Biorąc pod uwagę blok kodu. Uzupełnij tak, aby pętla stała się nieskończona.class ToInfinity {
public static void main(String[] args) {
//впишите kod сюда
for (int i = start; i <= start + 1; i++) {
/* тут должен быть бесконечный цикл, менять ничего нельзя*/
}
}
}
„Nic skomplikowanego” – mówisz. Najprawdopodobniej nie raz znalazłeś się w takiej sytuacji: rozwiązując problemy z Javą, utworzyłeś nieskończoną pętlę i zastanawiałeś się, jak się jej pozbyć. Jest na odwrót. Sztuczka polega na tym, że samego cyklu i warunków wyjścia z niego nie da się zmienić. Są tylko dwie iteracje. Jest ich jednak wystarczająco dużo, aby utworzyć nieskończoną pętlę. Wygląda na to, że powinno działać tylko w dwóch iteracjach, ale można je uczynić nieskończonym, używając przepełnienia. Czy już zgadłeś jak?
Rozwiązanie
Z powodu przepełnienia.Integer.MAX_VALUE
to maksymalna wartość, jaką int
można zapisać w Javie. Jeśli osiągniesz Integer.MAX_VALUE
i zwiększysz tę wartość, zjedziesz w dół Integer.MIN_VALUE
do wartości minimalnej Integer
. Zatem, aby rozwiązać ten problem z Javą, wystarczy przypisać start
zmiennej wartość o 1 mniejszą od maksymalnej wartości dla danego typu danych int
. Kod zadania w Javie:
class ToInfinity {
public static void main(String[] args) {
int start = Integer.MAX_VALUE - 1;
for (int i = start; i <= start + 1; i++) {
//бесконечный цикл
System.out.println(i); //убеждаемся в бесконечности цикла
}
}
}
Co się dzieje? Zaczynamy od start=2147483645 (Integer.MAX_VALUE-1), w następnej iteracji wartość wynosi 2147483645, następnie 2147483646, następnie -2147483648, -2147483647... i tak dalej.
Zadanie Java 2. Utwórz komentarz, który zostanie wykonany
Cóż, oto jesteśmy! Już na pierwszych wykładach usłyszeliśmy, że komentarze nie są realizowane. Właśnie po to są komentarze. Uważamy, że rozwiązanie tego problemu nie zawsze jest oczywiste dla programisty Java, nawet doświadczonego. Istnieje jednak jeden trudny sposób, aby zmusić maszynę Java do „legalnego” uruchomienia komentarza w celu wykonania. Czy czujesz, skąd wieje wiatr? Spróbuj zgadnąć!Rozwiązanie
Kod rozwiązujący problem w Javie:public class ExecutableComment {
public static void main(String[] args) {
// комментарий ниже будет выполнен!
// \u000d System.out.println("выполняемый комментарий");
}
}
Jeśli wpiszemy kod tego zadania w Javie w IDE, otrzymamy coś takiego:
выполняемый комментарий
Powodem jest to, że kompilator Java odczytuje znak Unicod \u000d
jako nową linię i czyta nasz kod w następujący sposób: Kompilator odszyfrował kod w celu rozwiązania problemu w Javie:
public class ExecutableComment {
public static void main(String[] args) {
// the line below this gives an output
// \u000d
System.out.println("comment executed");
}
}
Zadanie Java - 3: Utwórz nazwaną pętlę
Kolejny przedstawiciel cyklu „Praktyczne problemy programowania, Java w sferycznej próżni”. W tym sensie, że nie jest jasne, dlaczego jest to konieczne, jest mało prawdopodobne, aby cykl poczuł się urażony faktem, że jest bezosobowy. No cóż, ważne jest coś innego: język pozwala nadać cyklowi nazwę.Rozwiązanie
Uwaga: dla niektórych takie „nazwy” nazywane są „znacznikami”, których nie zaleca się stosować w praktyce. Kod rozwiązujący problem w Javie, demonstrujący nazwaną pętlępublic class NamedLoop {
public static void main(String[] args) {
loop1:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i == 3)
break loop1;
System.out.println("i = " + i + " j = " + j);
}
}
}
}
Oto jaki będzie wynik, jeśli uruchomisz program:
i = 0 j = 0
i = 0 j = 1
i = 0 j = 2
i = 0 j = 3
i = 0 j = 4
i = 1 j = 0
i = 1 j = 1
i = 1 j = 2
i = 1 j = 3
i = 1 j = 4
i = 2 j = 0
i = 2 j = 1
i = 2 j = 2
i = 2 j = 3
i = 2 j = 4
Tutaj możesz także użyć opcji kontynuuj, aby przejść na początek nazwanej pętli. A jeśli to konieczne, możesz użyć break
(lub continue
) w zagnieżdżonej pętli if-else
with for
-loop, aby rozdzielić kilka pętli za pomocą if-else
. Pomoże to uniknąć ustawiania wielu flag i testowania ich if-else
w celu ustalenia, czy kontynuować, czy wyjść z wewnętrznej pętli.
Problem w Javie - 4. O jedynym duplikacie w tablicy liczb całkowitych
Biorąc pod uwagę tablicę (lubArrayList
, jak wolisz) liczb całkowitych zawierających elementy Integer
od 1 do 100. Ta tablica ma jeden i tylko jeden zduplikowany element. Jak to znaleźć? Takie zadania są bardziej znane programiście Java niż trzy poprzednie. Bo nie chodzi tu o znajomość subtelności języka, z których prawie nigdy się nie korzysta, ale o logikę. Pierwszy nieokiełznany impuls do rozwiązania brutalną siłą dość szybko znika, gdy włącza się głowa lub pojawia się postawa „Jestem programistą, jestem mądry”. Jedyną złą rzeczą jest to, że podczas rozmowy kwalifikacyjnej, pod wpływem stresu, może się to nie zdarzyć. Więc pomyśl teraz, zanim zaczniesz szukać rozwiązania!
Algorytm rozwiązania jest następujący:
Oblicz sumę wszystkich liczb od 1 do 100. Myślimy, że wiesz jak to zrobić (np. korzystając ze słynnej metody Gaussa).Teraz oblicz sumę elementów swojej tablicy lubArrayList’а
. I... odejmij pierwszą kwotę od drugiej. Bingo! Wynikowa liczba jest wartością zduplikowanego elementu. Kod rozwiązania problemu Java dla ArrayList
.
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class FindDuplicate {
private static void findDuplicate(List<Integer> elements) {
//находим сумму всех уникальных элементов списка
int distinctSum = elements.stream().distinct().mapToInt(e -> e).sum();
//находим сумму всех элементов списка
int totalSum = elements.stream().mapToInt(e -> e).sum();
System.out.println("Элемент, который повторяется : " + (totalSum - distinctSum));
}
public static void main(String[] args) {
//создаем список последовательных элементов на промежутке [1..101).
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
//устанавливаем элементу с индексом 53 oznaczający 23
elements.set(53, 23);
findDuplicate(elements);
}
}
Inne rozwiązanie
import java.util.List;
import java.util.ArrayList;
public class Duplicate {
public int findDuplicateNumber(List<Integer> numbers) {
int highestNumber = numbers.size() - 1;
int total = getSum(numbers);
int duplicate = total - (highestNumber * (highestNumber + 1) / 2);
return duplicate;
}
public int getSum(List<Integer> numbers) {
int sum = 0;
for (int num : numbers) {
sum = sum + num;
}
return sum;
}
public static void main(String a[]) {
List <Integer> numbers = new ArrayList <Integer>();
for (int i = 1; i < 100; i++) {
numbers.add(i);
}
//добавляем дубликат в список
numbers.add(25);
Duplicate dn = new Duplicate();
System.out.println("Элемент, который повторяется: " + dn.findDuplicateNumber(numbers));
}
}
Problem w Javie - 5. O nieunikalnym duplikacie w tablicy liczb całkowitych
Jeśli poprzedni problem wydawał Ci się zbyt łatwy, spróbuj rozwiązać następujący: masz arkusz liczb całkowitych od 1 do 100. Zawiera duplikaty (więcej niż jeden). Jak znaleźć elementy, które występują więcej niż raz (znajdź sam element i wskaż, ile razy wystąpił)?Rozwiązanie
Najbardziej logicznym rozwiązaniem jest tutaj użycie struktury takiej jakHashMap
, ponieważ przechowuje ona dane w parach klucz-wartość. Kod rozwiązujący problem Java:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SomeDuplicates {
private static void findDuplicates(List<Integer> elements) {
HashMap <Integer, Integer > duplicates = new HashMap < >();
//заполняем Map duplicates значениями по принципу:
// ключ – oznaczający element, oznaczający – сколько раз он встречается
elements.forEach(e -> duplicates.put(e, duplicates.get(e) == null ? 1 : duplicates.get(e) + 1));
//из duplicates убираем все элементы, которые встретLubсь не более 1 раза,
//и сохраняем //результат в список (для удобства обработки на следующем шаге)
List <Map.Entry <Integer, Integer> >
result = duplicates.entrySet().stream().filter(d -> d.getValue() > 1).collect(Collectors.toList());
//выводим результат для всех элементов в списке result
result.forEach(e -> System.out.println(String.format("Элемент %d встречается %d раз", e.getKey(), e.getValue())));
}
public static void main(String[] args) {
List <Integer> elements = IntStream.range(1, 101).boxed().collect(Collectors.toList());
elements.set(97, 23);
elements.set(27, 51);
elements.set(99, 23);
findDuplicates(elements);
}
}
GO TO FULL VERSION