Increment Alpha-Numeric values but restrict to 3 characters - java

The scenario is - I read the last line of a file, increment it by one and write it back.
The read and write has been done. I am finding it difficult to increment the alpha-numberic values as it has a few conditions.
The conditions are:
It should only be 3 characters long
Example : A01, A02.... A99, B01, B02.... B99..
Once Z99 is reached it should be AA1, AA2, AA3...AA9, .....
Then AB1, AB2,... AZ9
So basically while incrementing the value should not go AA10 which makes it 4 characters
What I am doing now is separating the alphabets and integers, incrementing it and concatenating them back.
The code so far:
String[] part = lastLine.split("(?<=\\D)(?=\\d)");
System.out.println(part[0]);
System.out.println(part[1]);
int numberOnly = Integer.parseInt(lastLine.replaceAll("[^0-9]", ""));
numberOnly++;
String lettersOnly = lastLine.replaceAll("[^A-Z]", "");
if (lettersOnly.length() > 1){
String lastLetter = lettersOnly.substring(lettersOnly.length() - 1);
if(lastLetter.equalsIgnoreCase("Z") && number.equalsIgnoreCase("9") ){
String notLastLetter = lettersOnly.substring(lettersOnly.length() - 2);
char d = lettersOnly.charAt(0);
d++;
System.out.println("Letters after increment more tan two : " +d);
lettersOnly = Character.toString(d) + "Z";
}
}
else{
}
System.out.println("Letters after increment : " +lettersOnly);
Any help would be greatly appreciated.

public class AlphaNumericCounter {
String[] part;
int counter; //Variable storing numeric part of counter
String alpha; //Variable storing Alpha part of counter
static String final_output = "A00"; // First Input considered as A00 and also the variable which will be store each count
static boolean continueIncrement = true; //For running the loop till we reach ZZ9
/* Def constructor */
public AlphaNumericCounter() {
}
/* Constructor called from main method with primary input A00 */
public AlphaNumericCounter(String number) {
part = number.split("(?<=\\D)(?=\\d)");
}
/* Function called each time from inside loop to generate next alphanumeric count */
public void increment() {
part = final_output.split("(?<=\\D)(?=\\d)");
counter = Integer.valueOf(part[1]) + 1;
alpha = part[0];
}
public String toString() {
if (alpha.length() == 1){
if (String.valueOf(counter).length() > 2){
if ((int)alpha.charAt(0) + 1 > 90/*If Z encountered*/){
alpha = "AA";
}else{
alpha = String.valueOf((char)((int)alpha.charAt(0) + 1));//Take Next Alphabet
}
counter = 1; //Reset counter to 1
}
}else{
//We have AA, AB ... ZZ format of alpha
if (String.valueOf(counter).length() > 1){
if ((int)alpha.charAt(0) + 1 > 90 && (int)alpha.charAt(1) + 1 > 90){
continueIncrement = false;
System.out.println("NO MORE COMBINATION AVAILABLE"); //We reached ZZ
return "";
}else if ((int)alpha.charAt(1) + 1 <= 90){
alpha = String.valueOf((char)((int)alpha.charAt(0))) + String.valueOf((char)((int)alpha.charAt(1) + 1));
counter = 1;
}else if ((int)alpha.charAt(1) + 1 > 90){
if ((int)alpha.charAt(0) + 1 <= 90){
alpha = String.valueOf((char)((int)alpha.charAt(0) + 1)) + "A";
counter = 1;
}
}
}
}
generateString();
return final_output;
}
private void generateString(){
int l1 = String.valueOf(counter).length();
int l2 = alpha.length();
final_output = alpha + (l2 == 1 && l1 == 1 ? "0" : "") + String.valueOf(counter);
}
public static void main(String[] args) {
AlphaNumericCounter lic = new AlphaNumericCounter(final_output);
while (continueIncrement){
lic.increment();
System.out.println(lic);
}
}
}

What about incrementing each "digit" separatly from right to left and handle overvlow to the next digit:
String number;//number - is your originally string
char[] digits = number.toCharArray();
boolean overflow = true;
for(int i = 2; i >= 0; i--){
if(overflow){
switch(digits[i]){
case 'Z':
digits[i] = '0';
overflow = true;
break;
case '9':
digits[i] = 'A';
overflow = false;
break;
default:
digits[i]++;
overflow = false;
}
}
}
if(overflow){
//handle ZZZ overflow here
}
String result = new String(digits);

A simple solution is to count in Base36
Try this:
class AlphaNumericIncrementer {
public static void main(String[] args) {
/*
When starting at '000' => We hit 'zzz' (i.e. Dead End) at 46,656
When starting at 'A00' => We hit 'zzz' (i.e. Dead End) at 33,696
*/
int index = 0;
String currentNumber = "000";
while (index < 46656) {
index++;
String incrementedNumber = base36Incrementer(currentNumber, 36);
currentNumber = incrementedNumber;
if (incrementedNumber.toCharArray().length != 3) {
System.out.println("We got intruder with length: " + incrementedNumber.toCharArray().length);
System.out.println("Our Intruder is: " + incrementedNumber);
break;
}
System.out.println(incrementedNumber);
}
System.out.println("Number of entries: " + index);
}
// The function that increments current string
public static String base36Incrementer(String v, int targetBase) {
String answer = Integer.toString(Integer.parseInt(v, targetBase) + 1, targetBase);
return String.format("%3s", answer).replace(' ', '0');
}
}

Related

How do I find the decomposition of a string?

I need to create an algorithm for String decomposition.
Some examples:
ABCABCDEDEDEF --> ABC*2+DE*3+F
ABCcABCczcz --> ABC*2+cz*2+c
test --> test
Each segment of the string should be seperated by a + and, if repeated, followed up by a * plus the number of times it appears in succession.
This is what I have tried:
private static int[] prefixFunction(String source) {
int n = source.length();
int[] pi = new int[n];
for (int i = 1; i < n; i++) {
int j = pi[i - 1];
while (j > 0 && source.charAt(i) != source.charAt(j))
j = pi[j - 1];
if (source.charAt(i) == source.charAt(j))
j++;
pi[i] = j;
}
return pi;
}
This solution keeps everything in order, meaning an input like ABCABCDEDEDEF will return ABC*2+DE*3+F or an input like abDEDEab will return ab+DE*2+ab.
If you don't keep the order, it will be impossible to reconstruct the String later with 100 % accuracy.
public static void main(String[] args) {
String input = "ABCABCDEDEDEF";
String output = findDecomposition(input);
System.out.println("Output: " + output);
}
public static String findDecomposition(String input) {
String substring = input;
StringBuilder builder = new StringBuilder();
for (int start = 0, count = 1; start < input.length(); start++, count = 1) {
for (int end = start + 1; end < input.length(); end++) {
substring = input.substring(start, end);
while (true) {
String next = input.substring(start + substring.length(), Math.min(end + substring.length(), input.length()));
if (next.equals(substring)) {
count++;
start += substring.length();
end += substring.length();
} else
break;
}
if (count > 1) {
start += substring.length() - 1;
break;
}
}
if (count > 1) {
if (builder.length() > 0 && builder.charAt(builder.length() - 1) != '+')
builder.append('+');
builder.append(substring + "*" + count + "+");
} else
builder.append(input.charAt(start));
}
String result = builder.toString();
if (result.endsWith("+"))
return result.substring(0, result.length() - 1);
else
return result;
}
THe brute force alghoritm can work as follows.
Prerequisities:
First letter is set as root
Data structure of each possible solution is linked list. Value of each node is text to be written.
When outputting solution, first put to Map all text values together with number of appereances. If it appears more than once, use * as multiplicator
Example: One of the solution looks like this ABC-C-ABC, the output will be ABC*2+C
Solution:
Take next letter from input
New solutions are based on existing solutions. Each new solution is old solution + new letter added in one of the existing nodes or as single letter in new node.
Save new solutions as existing solutions.
Repeat from 1 until you process all letters
Calculate value of all solutions and select one with lowest string characters
I added example, as you can see the number of solutions are increasing quickly so it is not fully finished for all 6 letters. Each step represent the cycle from 1. to 4., you can see that in each step the previous solutions are used as base for new solutions. There are multiple new solutions created for each existing solution.
This code returns the following compositions:
ABCABCDEDEDEF -> ABC*2+DE*3+F
ABCcABCczcz -> ABCc*2+zcz
cefABCcABCczcz -> cef+ABCc*2+zcz
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class Decomposition {
public static void main(String[] args) {
Decomposition d = new Decomposition("ABCABCDEDEDEF");
System.out.println(d.getOptimalDecomposition());// Output: ABC*2+DE*3+F
d = new Decomposition("ABCcABCczcz");
System.out.println(d.getOptimalDecomposition());// Output: ABCc*2+zcz
d = new Decomposition("cefABCcABCczcz");
System.out.println(d.getOptimalDecomposition());// Output: cef+ABCc*2+zcz
}
private List> decompositions;
private String toDecompose;
public Decomposition(String toDecompose) {
decompositions = new ArrayList();
this.toDecompose = toDecompose;
}
public String getOptimalDecomposition() {
decompose(0, new ArrayList());
return calculateOptimal(convertToPartsMap());
}
private String calculateOptimal(List> partsCount) {
Collections.sort(partsCount, new SortDecompositions());
StringBuilder optimal = new StringBuilder();
for (int i = 0; i 1) {
optimal.append("*");
optimal.append(pc.count);
}
if (i != partsCount.get(0).size() - 1) {
optimal.append("+");
}
}
return optimal.toString();
}
private List> convertToPartsMap() {
List> partsMap = new ArrayList();
for (List parts : decompositions) {
List partsCount = new ArrayList();
String lastPart = null;
int curCount = 0;
for (int i = 0; i parts) {
if (nextChar == toDecompose.length()) {
decompositions.add(parts);
return;
}
char toAdd = toDecompose.charAt(nextChar);
if (parts.isEmpty()) {
parts.add("" + toAdd);
decompose(nextChar + 1, parts);
} else {
// left
List leftParts = parts.stream().collect(Collectors.toList());// shallow copy
if (!leftParts.isEmpty()) {
int last = leftParts.size() - 1;
leftParts.set(last, leftParts.get(last) + toAdd);
} else {
leftParts.add("" + toAdd);
}
// right
List rightParts = parts.stream().collect(Collectors.toList());// shallow copy
rightParts.add("" + toAdd);
decompose(nextChar + 1, leftParts);
decompose(nextChar + 1, rightParts);
}
}
}
class PartCount {
String part;
int count;
public PartCount(String part, int count) {
this.part = part;
this.count = count;
}
#Override
public String toString() {
return "[" + part + ", " + count + "]";
}
}
class SortDecompositions implements Comparator> {
public int compare(List a, List b) {
// Here you can define what exactly means "taking up least space".
return countChars(a) - countChars(b);
}
private int countChars(List listPc) {
int count = 0;
for (PartCount pc : listPc) {
count += pc.part.length();
}
return count;
}
}
This can be solved by using KMP alogorthm longest prefix which is also suffix
Steps:
iterate the string "ABCABCDEDEDEF" and construct lps array for the string. The values in the array will be
0 0 0 1 2 3 0 0 0 0 0 0 0
This lps array gives the number of times the prefix is repeated in the string.
In the above case it is repeated only one time. Considering the actual prefix number of times will be 2 it becomes ABC*2
Take the substring of the remaining string and repeat the step 1 till the end of the string.
I can provide you the code if needed. The worst time complexity will be O(n2)

How to avoid StackOverFlow in recursion?

I need to find the frequency of each character in a String using recursion.
Found this question online and wanted to do this as a challenge.
Have used two variables 'a' and 'i', where 'a' is used to store the index of the current character in the string that needs to be searched and 'i' is used to go through the entire string in search of the character that 'a' has extracted.
Finding the frequency of each character present in the word.
import java.util.*;
public class ini {
public static void main(String args[]) {
recur(0, 0, "Hello how are you", 0);
}
static private char m = ' ';
private static boolean recur(int a, int i, String s, int count) {
if (s.length() >= 1) {
if (a < s.length()) {
m = s.charAt(a);
if (i < s.length()) {
if (s.charAt(a) == s.charAt(i)) {
count += 1;
}
recur(a, ++i, s, count);
}
i = 0;
System.out.println(s.charAt(a) + ":" + count);
s = s.replaceAll(Character.toString(s.charAt(a)), "");
a += 1;
count = 0;
}
if (a != s.length() - 1) {
recur(a, i, s, count);
}
} else {
return false;
}
return true;
}
}
The current output ignores the letter "w" altogether
H:1
l:2
:3
o:3
r:1
y:1
Exception in thread "main" java.lang.StackOverflowError
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at...
There are a couple of things that we don't know:
Should h and H be considered only one character?
Should you count the spaces? (Programmatically speaking, space is a character)
Do you need an improved solution?
Are you allowed to do manipulate the initial text?
Some observations:
You need to rename your variables better
You don't need the static field
You don't need the recursive function to be boolean
a is used only for the identification of the character, and the increment is not needed
Quick solution:
private static void recur(int startingIndex, int recursionIndex, String text, int count) {
if (text.length() >= 1) {
if (startingIndex < text.length()) {
char currentCharacter = text.charAt(startingIndex);
if (recursionIndex < text.length()) {
if (currentCharacter == text.charAt(recursionIndex)) {
count += 1;
}
recur(startingIndex, ++recursionIndex, text, count);
} else {
System.out.println(currentCharacter + ":" + count);
text = text.replace(Character.toString(currentCharacter), "");
recur(0, 0, text, 0);
}
}
}
}
Improved solution:
public class Main {
public static void main(String[] args) {
recur(0, "Hello how are you", 0);
}
private static void recur(int index, String text, int count) {
if (text.length() >= 1) {
char currentCharacter = text.charAt(0);
if (index< text.length()) {
if (currentCharacter == text.charAt(index)) {
count += 1;
}
recur(++index, text, count);
} else {
System.out.println(currentCharacter + ":" + count);
text = text.replace(Character.toString(currentCharacter), "");
recur(0, text, 0);
}
}
}
}
The optimal solution without modifying the initial text:
private static int recur(char character, String text, int index) {
if (index >= text.length()) {
return 0;
}
int count = text.charAt(index) == character? 1 : 0;
return count + recur(text, character, index + 1);
}
After much tinkering I've figured it out. Basically you should not increment a. This will skip over letters and thus remove the line where a is incremented.a += 1; Furthermore, with recursion (I was struggling to remember myself) you want to be careful how you call the function you are in. If you don't make the recursive call as the last step (tail recursion), you will enter an infinite loop for various reasons here. All you need to do is add a return statement before the first recursive call and you will have solved it like so.
import java.util.*;
public class ini {
public static void main(String args[]) {
recur(0, 0, "Hello how are you", 0);
}
static private char m = ' ';
private static boolean recur(int a, int i, String s, int count) {
if (s.length() >= 1) {
if (a < s.length()) {
m = s.charAt(a);
if (i < s.length()) {
if (s.charAt(a) == s.charAt(i)) {
count += 1;
}
//Added crucial return statement
return recur(a, ++i, s, count);
}
i = 0;
System.out.println(s.charAt(a) + ":" + count);
s = s.replaceAll(Character.toString(s.charAt(a)), "");
//removed a += 1;
count = 0;
}
if (a != s.length() - 1) {
recur(a, i, s, count);
}
} else {
return false;
}
return true;
}
}
Output :
H:1
e:2
l:2
o:3
:3
h:1
w:1
a:1
r:1
y:1
Here is a link about tail vs. head recursion : Tail vs. Head Recursion
Hope this helps you!
My approach is slightly different from yours but you might find it interesting.
In my approach I am removing the character and checking the difference in the length of String. The change in length would be the times that character repeated. Rest is explained in the code.
public class CharactersFrequency {
public static void main(String[] args) {
CharactersFrequency cF = new CharactersFrequency();
long startTime = System.currentTimeMillis();
// I generated a sting with 1000 characters from a website
cF.frequencyOfCharacters("a quick brown fox jumps over the lazy dog");
long endTime = System.currentTimeMillis();
System.out.println("Runtime: " + (endTime - startTime) + " ms");
}
private void frequencyOfCharacters(String input) {
CharactersFrequency cF = new CharactersFrequency();
cF.frequencyOfCharactersRec(input, input.charAt(0) + "");
}
public void frequencyOfCharactersRec(String input, String currentChar) {
// If only one char is left
if (input.length() <= 1) {
System.out.println(currentChar + ": 1");
} else {
// Checking Initial length and saving it
int inputOldLength = input.length();
// Removing the char whose frequency I am checking
input = input.replace(currentChar, "");
// Checking new length
int inputNewLength = input.length();
// The difference between length should be the number of times that char
// repeated
System.out.println(currentChar + " : " + (inputOldLength - inputNewLength));
// In some cases after replace function the string becomes empty
// thus charAt(0) gives an error
if (inputNewLength > 0) {
frequencyOfCharactersRec(input, input.charAt(0) + "");
}
}
}
}
Output:
a : 2
: 8
q : 1
u : 2
i : 1
c : 1
k : 1
b : 1
r : 2
o : 4
w : 1
n : 1
f : 1
x : 1
j : 1
m : 1
p : 1
s : 1
v : 1
e : 2
t : 1
h : 1
l : 1
z : 1
y : 1
d : 1
g: 1
Runtime: 3 ms

Java: Find the longest sequential same character array

I am a new guy to java. I want to find the longest sequential same character array in a input character arrays. For example,this character array bddfDDDffkl, the longest is DDD, and this one: rttttDDddjkl, the longest is tttt.
I use the following code to deal with this problem. But, I want to improve my code, For example, if there are two same length arrays (for example rtttgHHH, there are two longest: ttt and HHH), how to solve this problem?
Thanks in advance.
My following code:
public class SeqSameChar {
public static void main (String[] args) {
int subLength = 0;
Scanner sc = new Scanner(System.in);
String[] num = null;
num = sc.nextLine().split(" ");
String[] number = new String[num.length];
for(int i = 0; i< number.length;i++) {
number[i] = String.valueOf(num[i]);
}
subLength =length(number,num.length);
System.out.println(subLength);
for(int i = index; i < index+subLength; i++) {
System.out.print(number[i]);
}
System.out.println(c==c1);
}
public static int index;
//to calculate the longest contiguous increasing sequence
public static int length(String[] A,int size){
if(size<=0)return 0;
int res=1;
int current=1;
for(int i=1;i<size;i++){
if(A[i].equals(A[i-1])){
current++;
}
else{
if(current>res){
index=i-current;
res=current;
}
current=1;
}
}
return res;
}
}
This algorithm will work perfectly fine for what you want to develop:
Before that, let me make it clear that if you want to check repeatitions of 2 different characters same number of times, you have to run a for loop in reverse to identify the 2nd character. So if the 2nd character is not same as the first one identified, and also if it's number of repeatitions are the same, you print both the characters or else, just print the single character you find at the first for loop because both the characters are going to be same.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter String 1: ");
String A1 = sc.nextLine();
MaxRepeat(A1);
}
public static void MaxRepeat(String A) {
int count = 1;
int max1 = 1;
char mostrepeated1 = ' ';
for(int i = 0; i < A.length()-1;i++) {
char number = A.charAt(i);
if(number == A.charAt(i+1)) {
count++;
if(count>max1) {
max1 = count;
mostrepeated1 = number;
}
continue;
}
count = 1;
}
count = 1;
int max2 = 1;
char mostrepeated2 = ' ';
for(int i = A.length()-1; i>0; i--) {
char number = A.charAt(i);
if(number == A.charAt(i-1)) {
count++;
if(count>max2) {
max2 = count;
mostrepeated2 = number;
}
continue;
}
count = 1;
}
if((max1==max2) && (mostrepeated1==mostrepeated2)) {
System.out.println("Most Consecutively repeated character is: " + mostrepeated1 + " and is repeated " + max1 + " times.");
}
else if((max1==max2) && (mostrepeated1!=mostrepeated2)) {
System.out.println("Most continously repeated characters are: " + mostrepeated1 + " and " + mostrepeated2 + " and they are repeated " + max1 + " times");
}
}
I'll give you a Scala implementation for that problem.
Here it is the automatic test (in BDD style with ScalaTest)
import org.scalatest._
class RichStringSpec extends FlatSpec with MustMatchers {
"A rich string" should "find the longest run of consecutive characters" in {
import Example._
"abceedd".longestRun mustBe Set("ee", "dd")
"aeebceeedd".longestRun mustBe Set("eee")
"aaaaaaa".longestRun mustBe Set("aaaaaaa")
"abcdefgh".longestRun mustBe empty
}
}
Following is the imperative style implementation, with nested loops and mutable variables as you would normally choose to do in Java or C++:
object Example {
implicit class RichString(string: String) {
def longestRun: Set[String] = {
val chunks = mutable.Set.empty[String]
val ilen = string.length
var gmax = 0
for ((ch, curr) <- string.zipWithIndex) {
val chunk = mutable.ListBuffer(ch)
var next = curr + 1
while (next < ilen && string(next) == ch) {
chunk += string(next)
next = next + 1
}
gmax = chunk.length max gmax
if (gmax > 1) chunks += chunk.mkString
}
chunks.toSet.filter( _.length == gmax )
}
}
}
Following is a functional-style implementation, hence no variables, no loops but tail recursion with result accumulators and pattern matching to compare each character with the next one (Crazy! Isn't it?):
object Example {
implicit class RichString(string: String) {
def longestRun: Set[String] = {
def recurse(chars: String, chunk: mutable.ListBuffer[Char], chunks: mutable.Set[String]): Set[String] = {
chars.toList match {
case List(x, y, _*) if (x == y) =>
recurse(
chars.tail,
if (chunk.isEmpty) chunk ++= List(x, y) else chunk += y,
chunks
)
case Nil =>
// terminate recursion
chunks.toSet
case _ => // x != y
recurse(
chars.tail,
chunk = mutable.ListBuffer(),
chunks += chunk.mkString
)
}
}
val chunks = recurse(string, mutable.ListBuffer(), mutable.Set.empty[String])
val max = chunks.map(_.length).max
if (max > 0) chunks.filter( _.length == max ) else Set()
}
}
}
For example, for the given "aeebceeedd" string, both implementations above will build the following set of chunks (repeating characters)
Set("ee", "eee", "dd")
and they will filter those chunks having the maximum length (resulting "eee").

java.lang.NumberFormatException for input string

I'm creating a program which makes the given input string into number so that input will be coded. But I'm running into a NumberFormatException as soon as the input string gets too long. I can't see how I can fix this.
Note that I have to get substrings from the given string input, turn them into numericValues then get the sum of these two strings as an answer.
Code:
public class Puzzle {
private static char[] letters = {'a','b','c','d','e','f','g','h','i', 'j','k','l','m','n','o','p','q','r','s',
't','u','v','w','x','y','z'};
private static String input;
private static String delimiters = "\\s+|\\+|//+|=";
public static void main(String[]args)
{
input = "youuu + are = gay"; //as soon as the substrings before = sign are
//longer than 5 characters the exception occurs
System.out.println(putValues(input));
}
//method to put numeric values for substring from input
#SuppressWarnings("static-access")
public static long putValues(String input)
{
Integer count = 0;
long answer = 0;
String first="";
String second = "";
StringBuffer sb = new StringBuffer(input);
int wordCounter = Countwords();
String[] words = countLetters();
System.out.println(input);
if(input.isEmpty())
{
System.out.println("Sisestage mingi s6na");
}
if(wordCounter == -1 ||countLetters().length < 1){
return -1;
}
for(Character s : input.toCharArray())
{
for(Character c : letters)
{
if(s.equals(c))
{
count = c.getNumericValue(c);
System.out.print(s.toUpperCase(s) +"="+ count + ", ");
}
}
if(words[0].contains(s.toString()))
{
count = count - 1;
count = s.getNumericValue(s);
//System.out.println(count);
first += count.toString();
}
if(words[3].contains(s.toString())){
count = s.getNumericValue(s);
second += count.toString();
}
}
try {
answer = Integer.parseInt(first) + Integer.parseInt(second);
} catch(NumberFormatException ex)
{
System.out.println(ex);
}
System.out.println("\n" + first + " + " + second + " = " + answer);
return answer;
}
public static int Countwords()
{
String[] countWords = input.split(" ");
int counter = countWords.length - 2;
if(counter == 0) {
System.out.println("Sisend puudu!");
return -1;
}
if(counter > 1 && counter < 3) {
System.out.println("3 sõna peab olema");
return -1;
}
if(counter > 3) {
System.out.println("3 sõna max!");
return -1;
}
return counter;
}
//method which splits input String and returns it as an Array so i can put numeric values after in the
//putValue method
public static String[] countLetters()
{
int counter = 0;
String[] words = input.split(delimiters);
for(int i = 0; i < words.length;i++) {
counter = words[i].length();
if(words[i].length() > 18) {
System.out.println("Yhe s6na maksimaalne pikkus on 18 t2hem2rki ");
}
}
return words;
}
Integers in Java (as in many languages) are limited by a minimum and maximum value.
More information on this can be found here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
You could give a meaningful error in the catch-block
You did not enter a valid 32-bit Integer value.
Or you could switch to something like a BigDecimal which can hold bigger values: https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
(watch out: BigDecimal works very different from a normal int, so read the documentation wisely, and Google for examples if necessary)
EDIT: you can parse it to Long as well, if you want that: Long.parseLong(INPUT, 10);. That way you extend the limit to 64-bit.

Convert letter to digits

I want to change the letters A to point 1 and so the letter Z to be number 26, then changed again to number 27 letters AA, AB to 28. How do I? Do I have to use the "switch"? I use java program.
Did not test this, but something along these lines should work:
public String numberToCharacterRepresentation(int number) {
char[] ls = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
String r = "";
while(true) {
r = ls[number % 26] + r;
if(number < 26) {
break;
}
number /= 26;
}
return r;
}
The reverse:
public int stringToNumber(String str) {
char[] ls = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
Map<Character, Integer> m = new HashMap<Character, Integer>();
int j = 0;
for(char c: ls) {
m.put(c, j++);
}
int i = 0;
int mul = 1;
for(char c: new StringBuffer(str).reverse().toString().toCharArray()) {
i += m.get(c) * mul;
mul *= ls.length;
}
return i;
}
Use the Character object 0=>0 a=>10, etc If you only use letters then subtract 10
Character.forDigit(10,Character.MAX_RADIX) //will return 'a'
Character.getNumericValue('a') // will return 10
A simple solution is to treat the problem like writing letters instead of digits.
public static String asLetters(long num) {
StringBuilder sb = new StringBuilder();
while(num > 0) {
sb.append((char) ('#' + num % 26));
num /= 26;
}
return sb.toString();
}
For those of you wanting to do this for Excel:
public String getEquivColumn(int number){
String converted = "";
// Repeatedly divide the number by 26 and convert the
// remainder into the appropriate letter.
while (number >= 0)
{
int remainder = number % 26;
converted = (char)(remainder + 'A') + converted;
number = (number / 26) - 1;
}
return converted;
}
How about using c-'A'+1 to convert the letter in c to the number you want? Calculating the next place would be the same except add 27 instead. Basically what you're doing is converting a base-26 number to decimal except you have no zero.
This will do the job.
public String map(int i) {
String res = "";
if (i <= 0) {
throw new IllegalArgumentException("Can only map +ve numbers");
}
while (i > 0) {
res = Character.toString('A' + ((i - 1) % 26)) + res;
i = i / 26;
}
return res;
}
A more complicated version using a StringBuilder would be a more efficient, but this one is easier to understand.
Perhaps the simplest way for A-Z would be something like:
char c = *whatever letter you need*;
int cAsInt = Integer.toString(c - '#'); // # is 1 less than A
For things like AA, BB, etc., it would depend on how many combinations you need. Setting up a mapping might be quickest, but if the possibilities are endless, you'll have to figure out some formula.
import javax.swing.JOptionPane;
public class TBesar{
public static long x(int a, int b){
if (b==0){
return(1);
}
else{
return(a*(x(a,(b-1))));
}
}
public static long KatakeAngka(String nama){
int A = 0;
int B = 26;
long C = 0;
long Z;
int panjang = nama.length();
char namas[] = new char[panjang];
for (int i=0;i<panjang;i++){
namas[i] = nama.charAt(i);
switch (namas[i]){
case 'a' : A=1;break;
case 'b' : A=2;break;
case 'c' : A=3;break;
case 'd' : A=4;break;
case 'e' : A=5;break;
case 'f' : A=6;break;
case 'g' : A=7;break;
case 'h' : A=8;break;
case 'i' : A=9;break;
case 'j' : A=10;break;
case 'k' : A=11;break;
case 'l' : A=12;break;
case 'm' : A=13;break;
case 'n' : A=14;break;
case 'o' : A=15;break;
case 'p' : A=16;break;
case 'q' : A=17;break;
case 'r' : A=18;break;
case 's' : A=19;break;
case 't' : A=20;break;
case 'u' : A=21;break;
case 'v' : A=22;break;
case 'x' : A=23;break;
case 'w' : A=24;break;
case 'y' : A=25;break;
case 'z' : A=26;break;
}
int D = panjang-(i+1);
Z = (x(B,D))*A;
C = C+Z;
}return(C);
}
public static String hitung(long angka){
String B ;
if(angka<27){
if(angka==1){
B="a";
}else if(angka==2){
B="b";
}else if(angka==3){
B="c";
}else if(angka==4){
B="d";
}else if(angka==5){
B="e";
}else if(angka==6){
B="f";
}else if(angka==7){
B="g";
}else if(angka==8){
B="h";
}else if(angka==9){
B="i";
}else if(angka==10){
B="j";
}else if(angka==11){
B="k";
}else if(angka==12){
B="l";
}else if(angka==13){
B="m";
}else if(angka==14){
B="n";
}else if(angka==15){
B="o";
}else if(angka==16){
B="p";
}else if(angka==17){
B="q";
}else if(angka==18){
B="r";
}else if(angka==19){
B="s";
}else if(angka==20){
B="t";
}else if(angka==21){
B="u";
}else if(angka==22){
B="v";
}else if(angka==23){
B="w";
}else if(angka==24){
B="x";
}else if(angka==25){
B="y";
}else{B="z";}
return(B);
}
else{
return(hitung(angka/26)+hitung(angka%26));
}
}
public static void main (String [] args){
String kata = JOptionPane.showInputDialog(null,"Masukkan Kata ke 1");
String kata2 = JOptionPane.showInputDialog(null, "Masukkan Kata ke 2");
long hasil = KatakeAngka(kata);
long hasil2 = KatakeAngka(kata2);
long total = hasil+hasil2;
String HasilKata = hitung(total);
JOptionPane.showMessageDialog(null,kata+" = "+hasil+"\n"+kata2+" = "+hasil2+"\n"+kata+" + "+kata2+" = "+HasilKata);
}
}
This will work for A to ZZ :
public static int columnCharToNumber(String str) {
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(str.length() == 1) {
return alphabet.indexOf(str);
}
if(str.length() == 2) {
return ( alphabet.indexOf(str.substring(1)) + 26*(1+alphabet.indexOf(str.substring(0,1)))) ;
}
return -1;
}

Categories