สำหรับ นักเรียนJavaRushความท้าทายด้านการเขียนโปรแกรม Java และเครื่องมือตรวจสอบความถูกต้องเป็นเพื่อนที่ดีที่สุด อย่างไรก็ตาม ถึงเวลาสำหรับนักพัฒนาซอฟต์แวร์ทุกคน Padawan เมื่อคุณจำเป็นต้องเริ่มต้นจากเส้นทางที่ไม่มีใครเคยรู้จัก สร้างมินิโปรเจ็กต์สำหรับตัวคุณเอง และเตรียมพร้อมสำหรับการสัมภาษณ์ ในการสัมภาษณ์ ดูเหมือนว่าคุณควรจะพบกับปัญหา Java ในทางปฏิบัติแบบเดียวกับในหลักสูตร ในกรณีส่วนใหญ่สิ่งนี้เป็นจริง แต่บางบริษัทชอบถามคำถามหลอกลวงหรืออะไรที่ผิดปกติ เพื่อหลีกเลี่ยงความสับสนในระหว่างการสัมภาษณ์ที่ตึงเครียด การลองแก้ไขปัญหา Java ด้วยตนเองที่บ้านจะเป็นประโยชน์
ในบทความนี้เราจะดูงานที่ยุ่งยากเหล่านี้ครึ่งโหล เราขอแนะนำให้คุณอ่านเงื่อนไขก่อนแล้วลองแก้ไขด้วยตนเอง และอีกอย่างคืออย่าลืมแก้ปัญหา Java จากคอร์สทุกวันนะ!
- ภารกิจที่ 1: การสร้างวงวนไม่สิ้นสุดตั้งแต่เริ่มต้น
- งาน-2 สร้างความคิดเห็นที่จะดำเนินการ
- ภารกิจที่ 3: สร้างลูปที่มีชื่อ
- งาน-4 เกี่ยวกับการซ้ำกันครั้งเดียวในอาร์เรย์ของจำนวนเต็ม
- งาน-5 เกี่ยวกับการซ้ำกันที่ไม่ซ้ำกันในอาร์เรย์ของจำนวนเต็ม
ปัญหา Java - 1: การสร้างวงวนไม่สิ้นสุดตั้งแต่เริ่มต้น
รับบล็อกของรหัส ทำให้มันสมบูรณ์เพื่อให้วงกลายเป็นอนันต์class ToInfinity {
public static void main(String[] args) {
//впишите code сюда
for (int i = start; i <= start + 1; i++) {
/* тут должен быть бесконечный цикл, менять ничего нельзя*/
}
}
}
“ไม่มีอะไรซับซ้อน” คุณพูด เป็นไปได้มากว่าคุณพบว่าตัวเองอยู่ในสถานการณ์นี้มากกว่าหนึ่งครั้ง: ในขณะที่แก้ไขปัญหา Java คุณได้สร้างวงวนที่ไม่สิ้นสุดและคิดว่าจะกำจัดมันอย่างไร มันเป็นวิธีอื่น ๆ เคล็ดลับก็คือว่าตัววงจรเองและเงื่อนไขในการออกไม่สามารถเปลี่ยนแปลงได้ มีเพียงสองครั้งเท่านั้น อย่างไรก็ตาม มีมากพอที่จะสร้างวงวนไม่สิ้นสุด ดูเหมือนว่าควรจะใช้ได้เฉพาะการวนซ้ำสองครั้งเท่านั้น แต่สามารถทำให้ไม่มีที่สิ้นสุดได้โดยใช้โอเวอร์โฟลว์ คุณเคยเดาแล้วหรือยัง?
สารละลาย
เนื่องจากมีน้ำล้นInteger.MAX_VALUE
เป็นค่าสูงสุดที่int
สามารถเก็บไว้ใน Java หากคุณถึง และ เพิ่มInteger.MAX_VALUE
ค่านี้ คุณจะเลื่อนลงไปที่Integer.MIN_VALUE
ซึ่งก็คือค่าต่ำสุด ดังนั้น เพื่อแก้ ปัญหา Integer
Java นี้ เราเพียงแค่ต้องกำหนดstart
ค่าให้กับตัวแปรที่น้อยกว่าค่าสูงสุดสำหรับประเภทข้อมูล 1 รหัสงานใน Java:int
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); //убеждаемся в бесконечности цикла
}
}
}
เกิดอะไรขึ้น? เราเริ่มต้นด้วย start=2147483645 (Integer.MAX_VALUE-1) ในการวนซ้ำครั้งถัดไป ค่าจะกลายเป็น 2147483645 จากนั้น 2147483646 จากนั้น -2147483648, -2147483647... ไปเรื่อยๆ
Java Task-2 สร้างความคิดเห็นที่จะดำเนินการ
เอาล่ะเราอยู่ที่นี่แล้ว! จากการบรรยายครั้งแรกเราได้ยินมาว่าความคิดเห็นไม่ได้ถูกดำเนินการ นั่นคือสิ่งที่พวกเขาแสดงความคิดเห็น เราคิดว่าวิธีแก้ปัญหานี้ไม่ได้ชัดเจนสำหรับโปรแกรมเมอร์ Java เสมอไป แม้แต่ผู้ที่มีประสบการณ์แล้วก็ตาม อย่างไรก็ตาม มีวิธีที่ยุ่งยากวิธีหนึ่งในการบังคับให้เครื่อง Java รันความคิดเห็นเพื่อดำเนินการ "ถูกกฎหมาย" คุณรู้สึกถึงลมที่พัดมาจากไหน? ลองเดาสิ!สารละลาย
รหัสสำหรับการแก้ปัญหาใน Java:public class ExecutableComment {
public static void main(String[] args) {
// комментарий ниже будет выполнен!
// \u000d System.out.println("выполняемый комментарий");
}
}
หากเราพิมพ์โค้ดสำหรับงานนี้ใน Java ใน IDE นี่คือสิ่งที่เราได้รับ:
выполняемый комментарий
เหตุผลก็คือคอมไพเลอร์ Java อ่านอักขระ Unicod \u000d
เป็นบรรทัดใหม่และอ่านโค้ดของเราดังต่อไปนี้: คอมไพเลอร์ถอดรหัสโค้ดสำหรับการแก้ปัญหาใน Java:
public class ExecutableComment {
public static void main(String[] args) {
// the line below this gives an output
// \u000d
System.out.println("comment executed");
}
}
งาน Java - 3: สร้างลูปที่มีชื่อ
ตัวแทนอีกรายหนึ่งของซีรีส์ “ปัญหาการเขียนโปรแกรมเชิงปฏิบัติ Java ในสุญญากาศทรงกลม” ในแง่ที่ยังไม่ชัดเจนว่าเหตุใดจึงจำเป็น จึงไม่น่าเป็นไปได้ที่วงจรจะรู้สึกขุ่นเคืองกับข้อเท็จจริงที่ว่ามันไม่มีตัวตน โอเค มีอย่างอื่นที่สำคัญอีก: ภาษาช่วยให้คุณตั้งชื่อวงจรได้สารละลาย
หมายเหตุ: สำหรับบางคน "ชื่อ" ดังกล่าวเรียกว่า "แท็ก" ซึ่งไม่แนะนำให้ใช้ในทางปฏิบัติ โค้ดสำหรับแก้ไขปัญหาใน Java สาธิตการวนซ้ำที่มีชื่อ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);
}
}
}
}
นี่คือผลลัพธ์ที่ได้หากคุณรันโปรแกรม:
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
ที่นี่คุณสามารถใช้ Continue เพื่อไปยังจุดเริ่มต้นของลูปที่มีชื่อได้ และหากจำเป็น คุณสามารถใช้break
(หรือcontinue
) ในการซ้อนif-else
กับfor
-loop เพื่อแยกหลายลูปโดยใช้if-else
. ซึ่งจะช่วยหลีกเลี่ยงการตั้งค่าแฟล็กจำนวนมากและทดสอบif-else
เพื่อดูว่าจะดำเนินการต่อหรือออกจากลูปด้านใน
ปัญหา Java - 4. เกี่ยวกับการซ้ำกันเพียงรายการเดียวในอาร์เรย์ของจำนวนเต็ม
กำหนดอาร์เรย์ (หรือArrayList
ตามที่คุณต้องการ) ของจำนวนเต็มที่มีองค์ประกอบInteger
ตั้งแต่ 1 ถึง 100 อาร์เรย์นี้มีองค์ประกอบที่ซ้ำกันเพียงองค์ประกอบเดียวเท่านั้น จะหามันได้อย่างไร? งานดังกล่าวคุ้นเคยกับโปรแกรมเมอร์ Java มากกว่าสามงานก่อนหน้านี้ เพราะมันไม่ได้เกี่ยวกับการรู้รายละเอียดปลีกย่อยของภาษาที่แทบไม่เคยใช้ แต่เป็นเรื่องเกี่ยวกับตรรกะ แรงกระตุ้นที่ไร้การควบคุมประการแรกในการแก้ปัญหาโดยใช้กำลังเดรัจฉานจะหายไปอย่างรวดเร็วเมื่อคุณเริ่มมีทัศนคติหรือมีทัศนคติว่า "ฉันเป็นโปรแกรมเมอร์ ฉันฉลาด" สิ่งเดียวที่แย่คือในระหว่างการสัมภาษณ์ ภายใต้ความเครียด สิ่งนี้อาจไม่เกิดขึ้น ดังนั้นคิดตอนนี้ก่อนที่จะพิจารณาวิธีแก้ปัญหา!
อัลกอริธึมการแก้ปัญหามีดังนี้:
คำนวณผลรวมของตัวเลขทั้งหมดตั้งแต่ 1 ถึง 100 เราคิดว่าคุณรู้วิธีการทำเช่นนี้ (เช่น การใช้วิธี Gauss อันโด่งดัง) ตอนนี้ให้คำนวณผลรวมขององค์ประกอบของอาร์เรย์ของคุณArrayList’а
หรือ และ... ลบจำนวนแรกจากจำนวนที่สอง บิงโก! หมายเลขผลลัพธ์คือค่าขององค์ประกอบที่ซ้ำกัน รหัสวิธีแก้ปัญหา Java สำหรับ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 meaning 23
elements.set(53, 23);
findDuplicate(elements);
}
}
วิธีแก้ปัญหาอื่น
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));
}
}
ปัญหา Java - 5. เกี่ยวกับการซ้ำกันที่ไม่ซ้ำกันในอาร์เรย์ของจำนวนเต็ม
หากปัญหาก่อนหน้านี้ดูเหมือนง่ายเกินไปสำหรับคุณ ให้ลองแก้ไขปัญหาต่อไปนี้: ให้แผ่นจำนวนเต็มตั้งแต่ 1 ถึง 100 โดยมีจำนวนซ้ำกัน (มากกว่าหนึ่ง) จะค้นหาองค์ประกอบที่เกิดขึ้นมากกว่าหนึ่งครั้งได้อย่างไร (ค้นหาองค์ประกอบเองและระบุจำนวนครั้งที่เกิดขึ้น)สารละลาย
วิธีแก้ปัญหาที่สมเหตุสมผลที่สุดคือการใช้โครงสร้าง เช่นHashMap
เนื่องจากจะเก็บข้อมูลเป็นคู่คีย์-ค่า รหัสสำหรับการแก้ปัญหา 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 значениями по принципу:
// ключ – meaning element, meaning – сколько раз он встречается
elements.forEach(e -> duplicates.put(e, duplicates.get(e) == null ? 1 : duplicates.get(e) + 1));
//из duplicates убираем все элементы, которые встретorсь не более 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