Advertisement
Guest User

ppd java lab 1

a guest
Oct 14th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.34 KB | None | 0 0
  1. package model;
  2.  
  3.  
  4. import java.util.AbstractMap;
  5. import java.util.ArrayList;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8.  
  9. public class BigNumber {
  10.     private String numberAsString = "";
  11.  
  12.     public BigNumber(String numberAsString) {
  13.         for (char digit : numberAsString.toCharArray()) {
  14.             if (digit < '0' || digit > '9')
  15.                 throw new NumberFormatException("Given string can't be converted to a number");
  16.         }
  17.  
  18.         StringBuilder stringBuilder = new StringBuilder();
  19.         stringBuilder.append(numberAsString);
  20.         this.numberAsString = stringBuilder.reverse().toString();
  21.     }
  22.  
  23.     public BigNumber(int length) {
  24.         StringBuilder stringBuilder = new StringBuilder();
  25.         for(int i = 0; i < length; i++)
  26.             stringBuilder.append('0');
  27.  
  28.         numberAsString = stringBuilder.toString();
  29.     }
  30.  
  31.     public String get() {
  32.         numberAsString = numberAsString.replaceFirst("^0+(?!$)", "");
  33.         StringBuilder stringBuilder = new StringBuilder();
  34.         stringBuilder.append(numberAsString);
  35.         return stringBuilder.reverse().toString();
  36.     }
  37.  
  38.     public int getLength() { return numberAsString.length(); }
  39.  
  40.     public void addDigit(int digit) {
  41.         numberAsString = digit + numberAsString;
  42.     }
  43.     public void addDigit(char digit) {
  44.         numberAsString = digit + numberAsString;
  45.     }
  46.  
  47.     public BigNumber sumSequential(BigNumber otherBigNumber) {
  48.         int aLength = getLength();
  49.         int bLength = otherBigNumber.getLength();
  50.         int maxLength = Math.max(aLength, bLength);
  51.         int minLength = Math.min(aLength, bLength);
  52.  
  53.         BigNumber result = new BigNumber(maxLength + 1);
  54.  
  55.         int carry = 0;
  56.         for (int digitIndex = 0; digitIndex < minLength; digitIndex++) {
  57.             int aCurrentDigit = numberAsString.charAt(digitIndex) - '0';
  58.             int bCurrentDigit = otherBigNumber.numberAsString.charAt(digitIndex) - '0';
  59.  
  60.             int sumOfDigits = aCurrentDigit + bCurrentDigit + carry;
  61.             carry = sumOfDigits / 10;
  62.  
  63.             int resultingDigit = sumOfDigits % 10;
  64.             result.numberAsString += resultingDigit;
  65.         }
  66.  
  67.         if (aLength > minLength) {
  68.             for(int digitIndex = minLength; digitIndex < maxLength; digitIndex++) {
  69.                 int currentDigit = numberAsString.charAt(digitIndex) - '0';
  70.  
  71.                 int sumOfDigits = currentDigit + carry;
  72.                 carry = sumOfDigits > 9 ? 1 : 0;
  73.                 int resultingDigit = sumOfDigits % 10;
  74.                 result.numberAsString += resultingDigit;
  75.             }
  76.             if (carry > 0)
  77.                 result.numberAsString += carry;
  78.         }
  79.         else if (bLength > minLength) {
  80.             for(int digitIndex = minLength; digitIndex < maxLength; digitIndex++) {
  81.                 int currentDigit = otherBigNumber.numberAsString.charAt(digitIndex) - '0';
  82.  
  83.                 int sumOfDigits = currentDigit + carry;
  84.                 carry = sumOfDigits > 9 ? 1 : 0;
  85.                 int resultingDigit = sumOfDigits % 10;
  86.                 result.numberAsString += resultingDigit;
  87.             }
  88.             if (carry > 0)
  89.                 result.numberAsString += carry;
  90.         }
  91.         else if (carry > 0)
  92.             result.numberAsString += carry;
  93.  
  94.         return result;
  95.     }
  96.  
  97.     public static BigNumber sumSequential(BigNumber first, BigNumber second) {
  98.         return first.sumSequential(second);
  99.     }
  100.  
  101.     class ThreadedBigNumber extends Thread {
  102.         private String partOfFirstNumber, partOfSecondNumber;
  103.         private String result = "";
  104.         private int carry;
  105.  
  106.         ThreadedBigNumber(String partOfFirstNumber, String partOfSecondNumber) {
  107.             this.partOfFirstNumber = partOfFirstNumber;
  108.             this.partOfSecondNumber = partOfSecondNumber;
  109.         }
  110.  
  111.         public String getResult() {
  112.             return result;
  113.         }
  114.         public int getCarry() {
  115.             return carry;
  116.         }
  117.  
  118.         @Override
  119.         public void run() {
  120.             int aLength = partOfFirstNumber.length();
  121.  
  122.             carry = 0;
  123.             for (int digitIndex = 0; digitIndex < aLength; digitIndex++) {
  124.                 int aCurrentDigit = partOfFirstNumber.charAt(digitIndex) - '0';
  125.                 int bCurrentDigit = partOfSecondNumber.charAt(digitIndex) - '0';
  126.  
  127.                 int sumOfDigits = aCurrentDigit + bCurrentDigit + carry;
  128.                 carry = sumOfDigits / 10;
  129.  
  130.                 int resultingDigit = sumOfDigits % 10;
  131.                 result += resultingDigit;
  132.             }
  133.         }
  134.     }
  135.  
  136.     public BigNumber sumMultiThreaded(BigNumber otherBigNumber) throws InterruptedException {
  137.         return sumMultiThreaded(otherBigNumber, 4);
  138.     }
  139.  
  140.     public BigNumber sumMultiThreaded(BigNumber otherBigNumber, int THREAD_COUNT) throws InterruptedException {
  141.         //adding 0 to make both numbers equal in size
  142.         int smallestLength = Math.min(getLength(), otherBigNumber.getLength());
  143.         if (getLength() == smallestLength) {
  144.             while (getLength() < otherBigNumber.getLength())
  145.                 numberAsString += '0';
  146.         }
  147.         else {
  148.             while (otherBigNumber.getLength() < getLength())
  149.                 otherBigNumber.numberAsString += '0';
  150.         }
  151.  
  152.         int actualLength = getLength();
  153.         if (THREAD_COUNT > actualLength)
  154.             THREAD_COUNT = actualLength;
  155.  
  156.  
  157.         //holding copies of the numbers to be able to remove stuff
  158.         String number1 = numberAsString;
  159.         String number2 = otherBigNumber.numberAsString;
  160.         ArrayList<ThreadedBigNumber> listOfThreads = new ArrayList<>();
  161.  
  162.         //splitting the numbers across THREAD_COUNT buckets
  163.         for (int THREAD_INDEX = 0; THREAD_INDEX < THREAD_COUNT; THREAD_INDEX++) {
  164.             //how many digits are there gonna be in the bucket
  165.             int digitCountForBucket = (actualLength * THREAD_INDEX + actualLength) / THREAD_COUNT - (actualLength * THREAD_INDEX) / THREAD_COUNT;
  166.  
  167.             //getting the substrings from the numbers and then deleting them
  168.             String subStrOfNumber1 = number1.substring(0, digitCountForBucket);
  169.             String subStrOfNumber2 = number2.substring(0, digitCountForBucket);
  170.  
  171.             number1 = number1.substring(digitCountForBucket);
  172.             number2 = number2.substring(digitCountForBucket);
  173.  
  174.             System.out.println("[*]Starting thread " + THREAD_INDEX + " to compute the sum of  " + subStrOfNumber1 + " and " + subStrOfNumber2);
  175.  
  176.             ThreadedBigNumber threadedBigNumber = new ThreadedBigNumber(subStrOfNumber1, subStrOfNumber2);
  177.             listOfThreads.add(threadedBigNumber);
  178.             threadedBigNumber.start();
  179.         }
  180.  
  181.         int carry = 0;
  182.         StringBuilder stringBuilder = new StringBuilder();
  183.  
  184.         for (int THREAD_INDEX = 0; THREAD_INDEX < THREAD_COUNT; THREAD_INDEX++) {
  185.             listOfThreads.get(THREAD_INDEX).join();
  186.  
  187.             String resultOfThread = listOfThreads.get(THREAD_INDEX).getResult();
  188.             int carryForNextPart = listOfThreads.get(THREAD_INDEX).getCarry();
  189.  
  190.             if (carry > 0) {
  191.                 Map.Entry<String, Integer> ret = addCarryToNumber(resultOfThread);
  192.  
  193.                 resultOfThread = ret.getKey();
  194.                 carryForNextPart = carryForNextPart | ret.getValue();
  195.             }
  196.  
  197.             stringBuilder.append(resultOfThread);
  198.  
  199.             carry = carryForNextPart;
  200.         }
  201.         if (carry > 0)
  202.             stringBuilder.append('1');
  203.  
  204.         return new BigNumber(stringBuilder.reverse().toString());
  205.     }
  206.  
  207.     private Map.Entry<String, Integer> addCarryToNumber(String number) {
  208.         int carry = 1;
  209.         StringBuilder stringBuilder = new StringBuilder();
  210.         stringBuilder.append(number);
  211.  
  212.         for(int digitIndex = 0; digitIndex < number.length(); digitIndex++) {
  213.             int digit = number.charAt(digitIndex) - '0';
  214.             int newDigit = (digit + 1) % 10;
  215.             stringBuilder.setCharAt(digitIndex, Character.forDigit(newDigit, 10));
  216.  
  217.             //if we stopped having a carry in the number, then no need to continue adding
  218.             if (digit + 1 <= 9) {
  219.                 carry = 0;
  220.                 break;
  221.             }
  222.         }
  223.  
  224.         number = stringBuilder.toString();
  225.         return new AbstractMap.SimpleEntry<>(number, carry);
  226.     }
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement