import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main
(String[] args
) { Main app = new Main();
app.run();
}
private void run() {
System.
out.
println(compress
("tttaaabbbcedg")); System.
out.
println(decompress
("t2a12bce"));
BigInt left = new BigInt("-701");
BigInt right = new BigInt("-29");
System.
out.
println(minus
(left, right
)); }
private class CharacterCount {
private char character;
private int count;
CharacterCount(char character) {
this(character, 1);
}
CharacterCount(char character, int count) {
this.character = character;
this.count = count;
}
void increment() {
this.count++;
}
void setCount(int count) {
this.count = count;
}
int getCount() {
return count;
}
char getCharacter() {
return character;
}
@Override
return "" + character + (count < 2 ? "" : count);
}
}
}
List<CharacterCount> characters = new ArrayList<>();
CharacterCount currentCharacter = new CharacterCount(plainText.charAt(0));
int plainTextLength = plainText.length();
for (int i = 1; i < plainTextLength; i++) {
final char character = plainText.charAt(i);
if (character == currentCharacter.getCharacter()) {
currentCharacter.increment();
continue;
}
characters.add(currentCharacter);
currentCharacter = new CharacterCount(character);
}
characters.add(currentCharacter);
return characters.stream().reduce("", (acc, c) -> acc + c, (l, r) -> l + r);
}
List<CharacterCount> characters = new ArrayList<>();
CharacterCount currentCharacter = new CharacterCount(encryptText.charAt(0));
boolean isDigit = true;
int encryptTextLength = encryptText.length();
for (int i = 1; i < encryptTextLength; i++) {
final char character = encryptText.charAt(i);
final int count
= Character.
getNumericValue(character
);
if (isDigit) {
currentCharacter.setCount(count);
isDigit = false;
continue;
}
currentCharacter.setCount(currentCharacter.getCount() * 10 + count);
continue;
}
characters.add(currentCharacter);
currentCharacter = new CharacterCount(character);
isDigit = true;
}
characters.add(currentCharacter);
return characters.stream().reduce("", (acc, c) -> acc + c.toRawString(), (l, r) -> l + r);
}
private class BigInt {
private int sign; // 0: positive, 1: negative
final char signCharacter = number.charAt(0);
if (signCharacter == '+') {
this.number = number.substring(1);
this.sign = 0;
} else if (signCharacter == '-') {
this.number = number.substring(1);
this.sign = 1;
} else {
this.number = number;
this.sign = 0;
}
this.number = new StringBuilder(this.number).reverse().toString();
}
private BigInt
(String number,
int sign
) { this.number = number;
this.sign = sign;
}
return new StringBuilder(number).reverse().toString();
}
void setNumber
(String number
) { this.number = new StringBuilder(number).reverse().toString();
}
int getSign() {
return sign;
}
void setSign(int sign) {
this.sign = sign;
}
@Override
return (sign == 0 ? "" : "-") + getNumber();
}
BigInt minus(BigInt right) {
final int leftSign = this.sign;
final int rightSign = right.sign;
if (leftSign == rightSign && this.number.equals(right.number)) {
return new BigInt("0");
}
if (leftSign == 1 && rightSign == 1) {
final BigInt positiveLeft = new BigInt(this.number, 0);
final BigInt positiveRight = new BigInt(right.number, 0);
return positiveRight.minus(positiveLeft);
}
if (leftSign == 0 && rightSign == 1) {
return new BigInt(this.addTwoPositive(right.number), 0);
} else if (leftSign == 1 && rightSign == 0) {
return new BigInt(this.addTwoPositive(right.number), 1);
}
// Case: Positive Left and Positive Right
if (this.number.length() < right.number.length()) {
return new BigInt(right.minusTwoPositive(this.number), 1);
} else if (this.number.length() > right.number.length()) {
return new BigInt(this.minusTwoPositive(right.number), 0);
}
int comparableResult = this.compareReverseNumber(right.number);
if (comparableResult == -1) {
return new BigInt(right.minusTwoPositive(this.number), 1);
}
if (comparableResult == 1) {
return new BigInt(this.minusTwoPositive(right.number), 0);
}
return null;
}
final int leftLength = left.length();
final int rightLength = right.length();
final int length
= Math.
max(leftLength, rightLength
);
if (leftLength < rightLength) {
left
= new StringBuilder
(left
).
append(String.
join( )).toString();
}
if (leftLength > rightLength) {
right
= new StringBuilder
(right
).
append(String.
join( )).toString();
}
StringBuilder builder = new StringBuilder();
int remainder = 0;
for (int i = 0; i < length; i++) {
int leftDigit
= Character.
getNumericValue(left.
charAt(i
)); int rightDigit
= Character.
getNumericValue(right.
charAt(i
));
Digit digit = add(leftDigit, rightDigit, remainder);
builder.append(digit.getDigit());
remainder = digit.getRemainder();
}
if (remainder > 0) {
builder.append(remainder);
}
return builder.toString();
}
final int length = left.length();
if (length > right.length()) {
right
= new StringBuilder
(right
).
append(String.
join( )).toString();
}
StringBuilder builder = new StringBuilder();
int remainder = 0;
for (int i = 0; i < length; i++) {
int leftDigit
= Character.
getNumericValue(left.
charAt(i
)); int rightDigit
= Character.
getNumericValue(right.
charAt(i
));
Digit digit = minus(leftDigit, rightDigit, remainder);
builder.append(digit.getDigit());
remainder = digit.getRemainder();
}
return builder.toString();
}
private Digit add(int left, int right, int remainder) {
int result = left + right + remainder;
if (result > 10) {
return new Digit(result - 10, 1);
}
return new Digit(result, 0);
}
private Digit minus(int left, int right, int remainder) {
right += remainder;
if (left < right) {
return new Digit(left + 10 - right, 1);
}
return new Digit(left - right, 0);
}
private int compareReverseNumber
(String right
) { int length = this.number.length();
for (int i = length - 1; i >= 0; i--) {
char leftChar = this.number.charAt(i);
char rightChar = right.charAt(i);
if (leftChar < rightChar) {
return -1;
} else if (leftChar > rightChar) {
return 1;
}
}
return 0;
}
}
private class Digit {
private int digit;
private int remainder;
Digit(int digit, int remainder) {
this.digit = digit;
this.remainder = remainder;
}
int getDigit() {
return digit;
}
void setDigit(int digit) {
this.digit = digit;
}
int getRemainder() {
return remainder;
}
void setRemainder(int remainder) {
this.remainder = remainder;
}
}
private BigInt minus(BigInt left, BigInt right) {
return left.minus(right);
}
}