diff --git a/problem-set/PrintThyself.MD b/problem-set/PrintThyself.MD new file mode 100644 index 0000000..0c1dec7 --- /dev/null +++ b/problem-set/PrintThyself.MD @@ -0,0 +1,32 @@ +# PrintThyself + +პრობლემა: +``` +დაწერეთ პროგრამა, რომელიც წაიკითხავს თAვის თავს ფაილიდან და დაბეჭდავს კონსოლში +``` + + + + +## პრობლემის გადაჭრის გზა +საკითხი ძალიან მარტივია, უპირველეს ყოვლისა უნდა ვცადოთ ფაილის გახსნა, შემდეგ კი წავიკითხოთ და შევინახოთ თითოეული ხაზი + +### როგორ გავხსნათ ფაილი? +ფაილის წასაკითხად საკმარისია გამოვიყენოთ `BufferedReader` და `FileReader` მეთოდები, რომლებიც `java.io` ბიბლიოთეკის ნაწილია. თუმცა მხოლოდ ეს როდია საკმარისი, თუ ფაილის სახელს არასწორად შევიყვანთ ან თუნდაც არარსებულ ფაილს მივუთითებთ მივიღებთ ბაგებს. თუმცა ამის ასარიდებლად შეგვიძლია გამოვიყენოთ `try { .. } catch { .. }`, შედეგად მივიღებთ შემდეგ კოდს + +```java + try{ + + BufferedReader br = new BufferedReader(new FileReader(fileName)); + //To-Do ... + + }catch(Exception e){ + //Error Message + } +``` + +### როგორ წავიკითხოთ ფაილიდან? +ეს ნაწილი საკმაოდ მარტივია, ფაილიდან ხაზის წაკითხვა შეგვიძლია `BufferedReader-ის` `readLine()` მეთოდის გამოყენებით, შესაბამისად შეგვიძლია ეს ფუნქცია მოვათავსოთ `While(true)` ციკლში, მაგრამ როდის უნდა გავაჩეროთ ციკლი? ესეც ძალიან მარტივია, მაშინ როდესაც `readLine()-ს` ფაილის დასასრულში ვიძახებთ ის აბრუნებს `null-ს`, ამიტომ შეგვიძლია ყოველ `readLine()-ს` გამოძახებას თან დავურთოთ შესაბამისი შემოწმებაც `if(readLine() == null) break;`. + +## შესაძლო ხარვეზები +ერთადერთი ხარვეზი რომელიც ზემოთ არ გაგვითვალიწნიებია გახლავთ - ფაილის დახურვა. მართალია ამ შემთხვევაში მოცემულ ამოცანას მაინც შეასრულებს ჩვენი კოდი, მაგრამ სხვა დროს, იმ შემთხვევაში თუ ფაილს არ დავხურავთ, შემდეგ კი მის ხელახლა გამოყენებას ვცდით მივიღებთ უამრავ შეცდომას და ვერც კი მივხვდებით რისი ბრალი შეიძლება იყოს. ამიტომ `while` ციკლის დასასრულს უბრალოდ შეგვიძლია დავწეროთ `br.close()` რომელიც დახურავს ჩვენს მიერ გახსნილ ფაილს diff --git a/problem-set/PrintThyself.java b/problem-set/PrintThyself.java new file mode 100644 index 0000000..5bfe9c7 --- /dev/null +++ b/problem-set/PrintThyself.java @@ -0,0 +1,61 @@ +/* File: PrintThyself.java + * --------------------------------- + * დაწერეთ პროგრამა რომელიც წაიკითხავს თავის თავს + * ფაილიდან და დაბეჭდავს კონსოლში + */ + +import java.io.BufferedReader; +import java.io.FileReader; + +import acm.graphics.GOval; +import acm.program.*; + +public class ConsoleProgrammSample extends ConsoleProgram { + + private static final String FILE_NOT_FOUND_MESSAGE = "- ERROR - Can't Locate Recevied File - ERROR -"; + + private String readFile(String fileName) { + + //Trying To Open File + try { + + String result = ""; + BufferedReader br = new BufferedReader(new FileReader(fileName)); + + while(true) { + + //Reading Every Line Of File + String newLine = br.readLine(); + //If newLine == null, It Means That There Are No More Line To Read, So While Loop Breaks + if(newLine == null) break; + + //Add newLine To "result" + result += newLine + '\n'; + } + + br.close(); + //Return Result + return result; + + }catch(Exception e) { + + System.out.print(e); + } + + //Return Error Message, If Code Catches Errors + return FILE_NOT_FOUND_MESSAGE; + } + + public void run(){ + + //Read File Content + String fileName = readLine("Enter FileName: "); + String result = readFile(fileName); + + //Print File Content + println("Received File Contains Text: "); + println(result); + + } + +} diff --git a/problem-set/images/ASCII_codes.png b/problem-set/images/ASCII_codes.png new file mode 100644 index 0000000..445bef6 Binary files /dev/null and b/problem-set/images/ASCII_codes.png differ diff --git a/problem-set/images/Initialization_error_stringToInteger.png b/problem-set/images/Initialization_error_stringToInteger.png new file mode 100644 index 0000000..41646b1 Binary files /dev/null and b/problem-set/images/Initialization_error_stringToInteger.png differ diff --git a/problem-set/images/Recursive_stringToInteger.png b/problem-set/images/Recursive_stringToInteger.png new file mode 100644 index 0000000..f8ee6d6 Binary files /dev/null and b/problem-set/images/Recursive_stringToInteger.png differ diff --git a/problem-set/images/stringToInteger_function.png b/problem-set/images/stringToInteger_function.png new file mode 100644 index 0000000..9d7626e Binary files /dev/null and b/problem-set/images/stringToInteger_function.png differ diff --git a/problem-set/images/stringToInteger_function_algorithm.png b/problem-set/images/stringToInteger_function_algorithm.png new file mode 100644 index 0000000..251fe7e Binary files /dev/null and b/problem-set/images/stringToInteger_function_algorithm.png differ diff --git a/problem-set/stringToInteger.java b/problem-set/stringToInteger.java new file mode 100644 index 0000000..0816ee0 --- /dev/null +++ b/problem-set/stringToInteger.java @@ -0,0 +1,41 @@ +/* File: StringToInteger.java + * --------------------------------- + * დაწერეთ stringToInteger მეთოდი, რომელსაც გადაეცემა სტრინგი და აბრუნებს მთელ რიცხვს. + * ჩათვალეთ, რომ გადაცემული სტრინგი მხოლოდ ციფრებისგან შედგება და არ იწყება 0-ით. + * მაგალითად “234” გადაცემის შემთხვევაში მეთოდმა უნდა დააბრუნოს 234. ასევე ჩათვალეთ, + * რომ დაბრუნებული მნიშვნელობა დადებითია და ეტევა int-ში. + */ + +import acm.program.*; + +public class ConsoleProgrammSample extends ConsoleProgram { + + //Function bellow transforms received string into the Integer + private int stringToInteger(String num) { + + int result = 0; + + for(int i = 0; i < num.length(); i++) { + result *= 10; + result += (num.charAt(i) - '0'); + } + + return result; + } + + public void run() { + + //Getting input from user + String num = readLine("Enter number in string: "); + + //Checking if received string is not empty + if(num.length() != 0) { + int result = stringToInteger(num); + println("Converted: " + result); + + }else { + println("No valid string received."); + } + } +} + diff --git a/problem-set/stringToInteger.md b/problem-set/stringToInteger.md new file mode 100644 index 0000000..53ada21 --- /dev/null +++ b/problem-set/stringToInteger.md @@ -0,0 +1,114 @@ +# StringToInteger + +პრობლემა: +``` +დაწერეთ stringToInteger მეთოდი, რომელსაც გადაეცემა სტრინგი და აბრუნებს მთელ რიცხვს. +ჩათვალეთ, რომ გადაცემული სტრინგი მხოლოდ ციფრებისგან შედგება და არ იწყება 0-ით. +მაგალითად “234” გადაცემის შემთხვევაში მეთოდმა უნდა დააბრუნოს 234. ასევე ჩათვალეთ, +რომ დაბრუნებული მნიშვნელობა დადებითია და ეტევა int-ში. +``` + + + + +## პრობლემის გადაჭრის გზა +ვინაიდან შემოსული სტრინგები ყოველთვის ვალიდურია, ამოცანა შეგვიძლია დავყოთ 2 ნაწილად. +1. წავიკითხოთ String +2. შევქმნათ მეთოდი, რომელსაც არგუმენტად გადაეცემა სტრინგი და უკან დაგვიბრუნებს შესაბამის Integer-ს. + + +--- + +### პირველი ნაბიჯი +უპირველეს ყოვლისა, უნდა წავიკითხოთ String-ი, ამისთვის გამოვიყენოთ მეთოდი `readLine(...)`, რომელსაც არგუმენტად შეგვიძლია გადავცეთ გამოსატანი ტექსტი, მაგალითად +`readLine("შეიყვანეთ რიცხვი: )` დაბეჭდავს ტექსტ "შეიყვანეთ რიცხვი: " და დაელოდება მომხმარებლის Input-ს. + +### მეორე ნაბიჯი +String-ის Integer-ად გარდასაქმნელად შევქმნათ ახალი მეთოდი `stringToInteger()`, რა თქმა უნდა, მოცემული მეთოდისთვის მოგვიწევს შემოსული String-ის გადაცემა,ამას გარდა მოგვიწევს გარდაქმნილი Integer-ის დაბრუნება, აქიდან გამომდინარე ჩვენი მეთოდი მიიღებს სახეს `private int stringToInteger(String num)`. + +![StringToInteger Function](/problem-set/images/stringToInteger_function.png) + +ახლა უკვე შეგვიძლია ჩვენს მთავარ პრობლემას მივხედოთ, ამოსახსნელი ალგორითმი არც თუ ისე რთულია, მარტივად გასაგებად განვიხილოთ 3 სიმბოლოიანი String, მაგალითად 321, ამასთანავე ჩავთვალოთ რომ ერთი სიმბოლოს Integer-ად გადაქცევა ვიცით (თუ როგორ მოგვიანებით ვიტყვით). ავიღოთ პირველი სიმბოლო ანუ 3 და შევინახოთ, მეორე სიმბოლოზე გადასვლისას კი შენახული რიცხვი ანუ 3 გავამრავლოთ 10-ზე და მას დავუმატოთ 2, ანალოგიურად მოვიქცეთ მესამე სიმბოლოზე გადასვლისასაც, ანუ შენახული 32 გავამრავლოთ 10-ზე და დავუმატოთ 1, თუ დავფიქრდებით რამდენჯერაც არ უნდა მოვიქცეთ მსგავსად ყოველთვის თავდაპირველ რიცხვს მივიღებთ. + +![StringToInteger Function Algorithm](/problem-set/images/stringToInteger_function_algorithm.png) + +ვინაიდან ალგორითმი უკვე განვიხილით შეგვიძლია კოდის წერასაც შევუდგეთ, განხილულის შემდეგ ალბათ ნათელია, რომ დაგვჭირდება `result` ცვლადი შესანახი მნიშვნელობებისთვის, ამასთანავე დაგვჭირდება თითოეული სიმბოლო String-დან, ამისთვის კი გამოვიყენეოთ `for` ციკლი, `string.length()` მეთოდი რომელიც შესაბამისი String-ის ზომას აბრუნებს და `string.charAt(index)` მეთოდი, რომელიც შესაბამისი სტრინგისთვი აბრუნებს გადაცემულ ინდექსზე მყოფ სიმბოლოს, მაგალითად შემდეგი კოდი დაგვიბეჭდავს `t სიმბოლოს`. + +```java +String test = "StringToInteger"; +println(test.charAt(1)); +``` + +დასასრულს გვრჩება ერთი დეტალი, როგორ ვაქციოთ სიმბოლო Integer-ად? ეს ძალიან მარტივია ვინაიდან თითოეულ სიმბოლოს აქვს თავისი ASCII მნიშვნელობა (იხ.სურათი), თუ ეს სიტყვა არაფერს გეუბნებათ ნუ ინერვიულებთ უბრალოდ ჩათვალეთ, რომ თითოეულ სიმბოლოს რაღაც განსაზღვურლი რიცხვი შეესაბამება, ამასთან ერთად კი ვიცითი რომ თუ სიმბოლო 0-ს შეესაბამება რაღაც x რიცხვი 1-ს აუცილებლად შეესაბამება მასზე 1 ით მეტი, 2-ს ორით მეტი და ა.შ, აქიდან გამომდინარე თუ ყოველ სიმბოლოს გამოვაკლებთ 0-ის ASCII კოდის მნიშვნელობას მივიღებთ სწორედ ამ სიმბოლოს Integer სახით. + +![ASCII Codes](/problem-set/images/ASCII_codes.png) + +ამ ყველაფრის გათვალისწინებით მივიღებთ შემდეგ კოდს: + +```java +int result = 0; + +for(int i = 0; i < num.length(); i++) { + result *= 10; + result += (num.charAt(i) - '0'); +} +``` + +აქ ნუ შეგაშინებთ ის მომენტი, რომ ჩვენ არა ASCII მნიშვნელობებს არამედ პირდაპირ სიმბოლოებს ვაკლებთ ერთმანეთს, ამ დროს კომპილატორმა იცის რომ ერთმანეთს სიმბოლოები კი არა არამედ მათი მნიშვნელობები უნდა გამოაკლოს ერთმანეთს. + +--- + +## შესაძლო ხარვეზები +* შეცდომა, რომელიც კოდის რეალიზაციისას შეიძლება დავუშვათ გახლავთ result ცვლადის შექმნა ინიციალიზაციის გარეშე, +ასეთ დროს არ ვიცით რა მნიშვნელობას იღებს result ცვლადისთვის განკუთვნილი კონტეინერი მეხსიერებაში, შესაბამისად შესაძლოა +საბოლოოდ სრულიად სხვა პასუხი მივიღოთ, ჩვენს შემთხვევაში კომპილატორი კოდის გაშვების შესაძლებლობასაც არ გვაძლევს. + +![Initialization Error StringToInteger](/problem-set/images/Initialization_error_stringToInteger.png) + +* მიუხედავად იმისა რომ ყოველი შემოსული რიცხვი დადებითია და ამასთან ერთად ეტევა Int-ის საზღვრებში, არ უნდა გამოგვრჩეს შემთხვევა როდესაც მომხმარებელს შემოყავს ცარიელი სტრინგი. ამ პრობლემის მოსაგვარებლად უბრალოდ მოგვიწვეს კოდიში ერთი `If-ის` ჩამატება. + +```java +if(string.length() != 0){ + //TO-DO... +}else{ + println("No input"); +} +``` + +--- + +## სხვა ამოხსნები +მოცემული ამოცანის ამოხსნა სხვა გზებითაც შეგვიძლია, მაგალითად რეკურსიის გამოყენებით, თუ ეს სიტყვა არაფერს გეუბნებათ ეს პრობლემას სულაც არ წარმოადგენს, ვინაიდან ამ ეტაპზე ამის ცოდნა სულაც არ მოგეთხოვებათ, თუმცა ვისაც გაგიგიათ, შეგიძლიათ იხილოთ სურათი სადაც იგივე მეთოდია აღწერილი ყველანაირი ციკლენიბ გარეშე. + +![Recursive StringToInteger](/problem-set/images/Recursive_stringToInteger.png) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +