From 5657b442e745a8e84e77e72052ae804aae338942 Mon Sep 17 00:00:00 2001 From: nghib20 Date: Mon, 14 Nov 2022 20:45:10 +0400 Subject: [PATCH] Implemented solution and explanation ReverseInts --- problem-set/ReverseInts.java | 47 ++++++++++++++++++++++++++++ problem-set/ReverseInts.md | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 problem-set/ReverseInts.java create mode 100644 problem-set/ReverseInts.md diff --git a/problem-set/ReverseInts.java b/problem-set/ReverseInts.java new file mode 100644 index 0000000..5a6673a --- /dev/null +++ b/problem-set/ReverseInts.java @@ -0,0 +1,47 @@ +/* + * File: ReverseInts.java + * ---------------------------- + * ReverseInts-ის საშუალებით მომხმარებლის მიერ შემოყვანილ რიცხვებს დავბეჭდავთ შებრუნებული მიმდევრობით. + * + * ამოცანის პირობა: + * კონსოლიდან შეგვყავს რიცხვები მანამ სანამ არ შეიყვანთ -1-ს, დაბეჭდეთ შეყვანილი რიცხვები შებრუნებული მიმდევრობით. + * + * დამატებითი ახსნის სანახავად იხილეთ /problem-set/ReverseInts.md + */ +import java.util.*; + +import acm.program.*; + +public class BlankClass extends ConsoleProgram { + private static final int SENTINEL = -1; + public void run() { + println("This program reverses the elements in an ArrayList."); + println("Use " + SENTINEL + " to signal the end of the list."); + ArrayList list = readArrayList(); + reversePrintArrayList(list); + } + /* + * This method reads user input and saves all + * values in an Integer ArrayList. After SENTINEL + * is entered, ArrayList is returned. + */ + private ArrayList readArrayList() { + ArrayList list = new ArrayList(); + while(true) { + int n = readInt("Enter a number: "); + if(n == SENTINEL) break; + list.add(n); + } + return list; + } + /* + * This method takes an Integer ArrayList and + * prints it's elements one by one in reverse. + */ + private void reversePrintArrayList(ArrayList list) { + int length = list.size(); + for(int i=length-1;i>=0;i--) { + println(list.get(i)); + } + } +} \ No newline at end of file diff --git a/problem-set/ReverseInts.md b/problem-set/ReverseInts.md new file mode 100644 index 0000000..ecacc51 --- /dev/null +++ b/problem-set/ReverseInts.md @@ -0,0 +1,60 @@ +# ReverseInts + +ამოცანა: +``` +კონსოლიდან შეგვყავს რიცხვები მანამ სანამ არ შეიყვანთ -1-ს, დაბეჭდეთ შეყვანილი +რიცხვები შებრუნებული მიმდევრობით. +``` +## ამოცანის ამოხსნა +ამოცანა დავყოთ ორ კომპონენტად: +* მომხმარებლის ინფუთის წაკითხვა და შენახვა. +* რიცხვების შებრუნებული მიმდევრობით დაბეჭდვა. +ორივე კომპონენტისთვის ცალკე მეთოდი დავწეროთ. + +### ინფუთის წაკითხვა და შენახვა +ინფუთის წასაკითხად გამოვიყენოთ ბრძანება `readInt()`. მომხმარებლისთვის ადვილად გასაგები რომ იყოს, `readInt()` ბრძანებას არგუმენტად გადავცეთ რაიმე სტრინგი. შემოსული რიცხვი კი ცვლადში შევინახოთ. ამოხსნის ეს ნაწილი კოდში შემდეგნაირად აისახება: +```java +int n = readInt("Enter a number: "); +``` +ამოცანის პირობის თანახმად, რიცხვები შეგვყავს მანამ, სანამ -1-ს არ შევიყვანთ. ე.ი. წინასწარ არ ვიცით რამდენი რიცხვი შემოდის. ასეთ შემთხვევაში გვჭირდება `while()` ციკლი. ყოველ იტერაციაზე წავიკითხავთ მომხმარებლის შემოყვანილ რიცხვს და შევანმოწმებთ -1 ხომ არ შემოიყვანა, რის შემთხვევაშიც ციკლი უნდა დავასრულოთ. კოდში ეს ასე აისახება: +```java +while(true) { + int n = readInt("Enter a number: "); + if(n == SENTINEL) break; +} +``` +ინფუთის წაკითხვის გარდა გვჭირდება მისი შენახვა. რადგანაც წინასწარ არ ვიცით რიცხვების რაოდენობა, შეგვიძლია `ArrayList` კლასი გამოვიყენოთ. ამისათვის დაგვჭირდება `java.util.*`-ის დაომპორტება: +```java +import java.util.*; +``` +შევქმნათ `ArrayList list` და ყოველი შემოსული რიცხვი შევინახოთ მასში (გარდა -1-ისა). როდესაც დავასრულებთ რიცხვების წაკითხვას, `list` დავაბრუნოთ. +ეს ყველაფერი ერთი მეთოდის ნაწილი იქნება, რომელსაც კითხვადობისათვის დავარქვათ `readArrayList()`. მთლიანობაში კოდს ასეთი სახე ექნება: +```java +private ArrayList readArrayList() { + ArrayList list = new ArrayList(); + while(true) { + int n = readInt("Enter a number: "); + if(n == SENTINEL) break; + list.add(n); + } + return list; +} +``` +### რიცხვების შებრუნებული მიმდევრობით დაბეჭდვა +შემოყვანილი რიცხვები `list`-ში გვაქვს დამახსოვრებული და ახლა მათი შებრუნებული თანმიმდევრობით დაბეჭდვა გვინდა. ეს `for()` ციკლით გავაკეთოთ. თუკი `list`-ს ბოლოდან გადავუყვებით და ყოველ ელემენტს დავბეჭდავთ, რიცხვები შებრუნებული მიმდევრობით დაიბეჭდება. ამისათვის შევინახოთ `list`-ის ზომა რაიმე ცვლადში და `for()` ციკლს შემდეგი სახე მივცეთ: +```java +int length = list.size(); +for(int i=length-1;i>=0;i--) { + println(list.get(i)); +} +``` +ამისთვისაც ცალკე მეთოდი გავაკეთოთ, რომელსაც არგუმენტად `list`-ს გადავცემთ. + +## რატომ იმუშავებს ამოხსნა ნებისმიერი შემოყვანილი მონაცემებისთვის? +რადგანაც მონაცემების წაკითხვა `while()` ციკლით გვიწერია, ამოხსნა იმუშავებს ნებისმიერი რაოდენობის ინფუთისთვის. `while()` ციკლი წაიკითხავს და შეინახავს რიცხვებს მანამ, სანამ მომხმარებელი -1-ს არ შემოიყვანს. + +## რატომ გამოვიყენეთ `ArrayList` და არა `Array`? +`Array`-ს შესაქმნელად აუცილებელია წინასწარ ვიცოდეთ მისი ზომა. `ArrayList`-ს კი ეს საჭიროება არ გააჩნია, რაც ძალიან გვეხმარება ამ ამოცანის ამოხსნაში. რადგანაც წინასწარ არ ვიცით რამდენ რიცხვს შემოიყვანს მომხმარებელი, ამიტომაც არის სასარგებლო `ArrayList`-ით დაწერა. `Array`-ს საშუალებითაც შეგვეძლო ამოხსნა, თუკი წინასწარ განსაზღვრული ზომის გაცდენის შემთხვევაში ახალ `Array`-ს შევქმნიდით და ძველის მნიშვნელობებს გადავაკოპირებდით, თუმცა `ArrayList`-ით ბევრად მარტივი და მოსახერხებელია. + +## რატომ არის -1 კონსტანტა? +-1 გატანილია როგორც მუდმივი მნიშვნელობა და აღნიშნულია `SENTINEL`-ით. ამ მიდგომას ის უპირატესობა აქვს, რომ -1-ის მაგივრად სხვა რიცხვის გამოყენება რომ გვინდოდეს წაკითხვის შესაჩერებლად, კოდს ადვილად შევცვლიდით. კონსტანტა კი იმიტომ არის, რომ მისი ცვლილება არ ხდებოდეს პროგრამის მიმდინარეობისას. \ No newline at end of file