Convert letter to digits - java

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;
}

Related

Decode String in Java

I am trying to convert this Python Solution in Java. For some reason, my Java Solution is not working. How can this be done correctly?
https://leetcode.com/problems/decode-string/description/
Given an encoded string, return its decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.
You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there will not be input like 3a or 2[4].
The test cases are generated so that the length of the output will never exceed 105.
Example 1:
Input: s = "3[a]2[bc]"
Output: "aaabcbc"
Example 2:
Input: s = "3[a2[c]]"
Output: "accaccacc"
Python Solution:
class Solution:
def decodeString(self, s: str) -> str:
stack = []
for char in s:
if char is not "]":
stack.append(char)
else:
sub_str = ""
while stack[-1] is not "[":
sub_str = stack.pop() + sub_str
stack.pop()
multiplier = ""
while stack and stack[-1].isdigit():
multiplier = stack.pop() + multiplier
stack.append(int(multiplier) * sub_str)
return "".join(stack)
Java Attempt:
class Solution {
public String decodeString(String s) {
Deque<String> list = new ArrayDeque<String>();
String subword = "";
String number = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != ']' ) {
list.add(String.valueOf(s.charAt(i)));
}
else {
subword = "";
while (list.size() > 0 && !list.getLast().equals("[") ) {
subword = list.pop() + subword;
}
if (list.size() > 0) list.pop();
number = "";
while (list.size() > 0 && isNumeric(list.getLast())){
number = list.pop() + number;
}
for (int j = 1; (isNumeric(number) && j <= Integer.parseInt(number)); j++) list.add(subword);
}
}
return String.join("", list);
}
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e){
return false;
}
}
}
The reason why your posted code is not working is because the pop() method in python removes the last element by default.
But in Java, the ArrayDeque class's pop() method removes the first element.
In order to emulate the python code with the ArrayDeque, you'll need to use the removeLast() method of the ArrayDeque instance instead.
public class Solution{
public static String decodeString(String s) {
StringBuilder stack = new StringBuilder();
for(char c : s.toCharArray()) {
if(c != ']') {
stack.append(c);
} else {
StringBuilder sub_str = new StringBuilder();
while(stack.charAt(stack.length() - 1) != '[') {
sub_str.insert(0, stack.charAt(stack.length() - 1));
stack.deleteCharAt(stack.length() - 1);
}
stack.deleteCharAt(stack.length() - 1);
StringBuilder multiplier = new StringBuilder();
while(stack.length() > 0 && Character.isDigit(stack.charAt(stack.length() - 1))) {
multiplier.insert(0, stack.charAt(stack.length() - 1));
stack.deleteCharAt(stack.length() - 1);
}
for(int i = 0; i < Integer.parseInt(multiplier.toString()); i++) {
stack.append(sub_str);
}
}
}
return stack.toString();
}
public static void main(String[] args) {
System.out.println( decodeString("3[a2[c]]"));
//Output: "accaccacc"
System.out.println( decodeString("3[a]2[bc]"));
//Output: "aaabcbc"
}
}

Why my code is incorrect (processing string)?

I'm currently doing an online course on hyperskill. There's a task:
The password is hard to crack if it contains at least A uppercase
letters, at least B lowercase letters, at least C digits and includes
exactly N symbols. Also, a password cannot contain two or more same
characters coming one after another. For a given numbers A, B, C, N
you should output password that matches these requirements.
And here's my code:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int upper = scan.nextInt();
int lower = scan.nextInt();
int digits = scan.nextInt();
int quantity = scan.nextInt();
String symbolsUpper = "QWERTYUIOPASDFGHJKLZXCVBNM";
String symbolsLower = "qwertyuiopasdfghjklzxcvbnm";
String symbolsDigits = "1234567890";
boolean exit = false;
Random random = new Random();
ArrayList<Character> password = new ArrayList<>();
if (upper > 0) {
for (int i = 0; i < upper; i++) {
password.add(symbolsUpper.charAt(random.nextInt(symbolsUpper.length())));
}
}
if (lower > 0) {
for (int k = 0; k < lower; k++) {
password.add(symbolsLower.charAt(random.nextInt(symbolsLower.length())));
}
}
if (digits > 0) {
for (int z = 0; z < digits; z++) {
password.add(symbolsDigits.charAt(random.nextInt(symbolsDigits.length())));
}
}
if (quantity - digits - upper - lower > 0) {
for (int m = 0; m < (quantity - digits - upper - lower); m++) {
password.add(symbolsDigits.charAt(random.nextInt(symbolsDigits.length())));
}
}
Collections.shuffle(password);
while (!exit) {
if (password.size() > 1) {
for (int i = 1; i < password.size(); i++) {
if (password.get(i).equals(password.get(i - 1))) {
char buffer = password.get(i);
password.remove(i);
password.add(buffer);
i--;
} else {
exit = true;
}
}
} else {
exit = true;
}
}
StringBuilder buildPassword = new StringBuilder();
for (Character character : password) {
buildPassword.append(character);
}
System.out.println(buildPassword);
}
}
When I run the code in IntelliJ IDEA, the program works just fine, however, the hyperskill platform doesn't accept this code as the right one.
The topic is "Processing string".
Can anyone here tell me please, what am I doing wrong? Is there a better way to write this code?
Can anyone here tell me please, what am I doing wrong?
The problem is that, due to the nature of random numbers, you might be very unlucky in the characters which are picked. This can result in two problems:
You can pick the same characters from the pool of characters. When you create a password using the input 0 0 0 2 it might be possible that two same digits are picked. As an example the password "55" can never satisfy the condition of having not two characters next to each other be the same, no matter how many time you shuffle it.
When the password is very long and you find two characters same next to each other you put one of the character to the end. This can happen twice for the same character. This means that the password "........44........44........." can result in the password ".........4.........4...........44", and now you have two same characters again (at the end).
Is there a better way to write this code?
Yes.
I don't know if you are trying for best performance, but here is a fun solution:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int uppers = scan.nextInt();
int lowers = scan.nextInt();
int digits = scan.nextInt();
int quantity = scan.nextInt();
int freeChoices = quantity - uppers - lowers - digits;
if (freeChoices < 0) {
System.exit(1);
}
ThreadLocalRandom r = ThreadLocalRandom.current();
StringBuilder password = new StringBuilder();
boolean isPasswordReady = false;
int lastUpper = -1, lastLower = -1, lastDigit = -1;
PasswordPart[] options = PasswordPart.values();
while (!isPasswordReady) {
int partChoice = r.nextInt(0, options.length);
switch (options[partChoice]) {
case DIGIT:
if (digits > 0 || freeChoices > 0) {
CharIndexHolder result = options[partChoice].get(lastDigit, -1, r);
password.append(result.c);
lastDigit = result.i;
if (digits == 0) {
freeChoices--;
} else {
digits--;
}
}
break;
case LOWER:
if (lowers > 0 || freeChoices > 0) {
CharIndexHolder result = options[partChoice].get(lastLower, lastUpper, r);
password.append(result.c);
lastLower = result.i;
if (lowers == 0) {
freeChoices--;
} else {
lowers--;
}
}
break;
case UPPER:
if (uppers > 0 || freeChoices > 0) {
CharIndexHolder result = options[partChoice].get(lastUpper, lastLower, r);
password.append(result.c);
lastUpper = result.i;
if (uppers == 0) {
freeChoices--;
} else {
uppers--;
}
}
break;
}
isPasswordReady = uppers == 0 && lowers == 0 && digits == 0 && freeChoices == 0;
}
System.out.println(password.toString());
}
enum PasswordPart {
UPPER("QWERTYUIOPASDFGHJKLZXCVBNM"), LOWER("qwertyuiopasdfghjklzxcvbnm"), DIGIT("1234567890");
private String pool;
PasswordPart(String pool) {
this.pool = pool;
}
public CharIndexHolder get(int lastIndex, int additionalIndex, ThreadLocalRandom random) {
int i = random.nextInt(0, pool.length());
while (i == lastIndex || i == additionalIndex) {
i = random.nextInt(0, pool.length());
}
return new CharIndexHolder(pool.charAt(i), i);
}
}
private static class CharIndexHolder {
char c;
int i;
CharIndexHolder(char c, int i) {
this.c = c;
this.i = i;
}
}

Increment Alpha-Numeric values but restrict to 3 characters

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');
}
}

Replacing multiple characters at a time

I'm trying to replace the string "abc" with certain patterns:
When 'a' replace with 'b', when 'b' replace with 'c', when 'c' replace with 'a'.
The code i have right now is :
String alp = "abc";
String alteredAlp = "";
char [] charAlp = alp.toLowerCase().toCharArray();
for (int i = 0; i < charAlp.length() - 1; i++)
{
if(charAlp[i] == 'a')
alteredAlp += 'b';
else if(charAlp[i] == 'b')
alteredAlp += 'c';
else if(charAlp[i] == 'c')
alteredAlp += 'a';
}
I tried using a 'replaceAll' and I was running into a couple issue after the first iteration.
Any ideas on how to make this better?
Thanks in advance!
There is no such method as length() for a char[]. Change that to charAlp.length
Next, change charAlp.length - 1 to charAlp.length and your code will work.
Instead, you can do something like this: (with no additional String)
for (int i = 0; i < charAlp.length ; i++)
{
if(charAlp[i] == 'a')
charAlp[i]= 'b';
else if(charAlp[i] == 'b')
charAlp[i]= 'c';
else if(charAlp[i] == 'c')
charAlp[i]= 'a';
}
System.out.println(charAlp);
Now, you changed charAlp to be "bca" instead of "abc" (as you wanted)
A little more generic way:
The Alphabet must be defined without gaps!
But can also be "abcdefgh" :)
public class CharObfuscator {
public static final String ALPHABET = "abc";
public static String obfuscate(String obfuscateThis) {
char bottomLevel = ALPHABET.charAt(0); // its an 'a' (int 97)
char topLevel = ALPHABET.charAt(ALPHABET.length() - 1); // its an 'c' (int 99)
StringBuilder stringBuilder = new StringBuilder();
for (char character : obfuscateThis.toLowerCase().toCharArray()) {
if ((character - bottomLevel + 1) % (topLevel - bottomLevel + 1) != 0) {
stringBuilder.append(++character);
} else {
stringBuilder.append(bottomLevel);
}
}
return stringBuilder.toString();
}
public static void main(String[] args) {
System.out.println(obfuscate("abccbaaabbcc"));
}
}
Result:
bcaacbbbccaa
public static void main(String[] args) {
String alp = "abc";
String alteredAlp = "";
for(int i=0; i<alp.length(); i++){
if(alp.charAt(i)=='a')
alteredAlp=alteredAlp + 'b';
else if(alp.charAt(i)=='b')
alteredAlp = alteredAlp+'c';
else if(alp.charAt(i)=='c')
alteredAlp=alteredAlp+'a';
}
System.out.println(alteredAlp);
}
Try this :
No need to create character array.
Output:
bca
You can also use a StringBuilder for the same, as below:
public class CharReplace {
public static void main(String[] args) {
String alp = "abc";
StringBuilder alteredAlp = new StringBuilder();
for (int i = 0; i < alp.length(); i++) {
switch(alp.charAt(i)) {
case 'a':
alteredAlp.append('b');
break;
case 'b':
alteredAlp.append('c');
break;
case 'c':
alteredAlp.append('a');
break;
}
}
System.out.println(alteredAlp.toString());
}
}

Stack problem java. Postfix Evaluation

Hey Guys I'm having a problem when I run my program. In the PostfixEvaluate() Method is where it takes in a string and solves the postfix problem and returns it. Well when I go to run it, I'm getting a bunch of random numbers(some repeated), I'm going crazy because I don't know what else to try and I've spent more time on this than it should normally take.
Heres the PostfixEvaluate Method:
public int PostfixEvaluate(String e){
//String Operator = "";
int number1;
int number2;
int result=0;
char c;
//number1 = 0;
//number2 = 0;
for(int j = 0; j < e.length(); j++){
c = e.charAt(j);
if (c != '+'&& c!= '*' && c!= '-' && c!= '/') {
//if (c == Integer.parseInt(e)) {
s.push(c);
}
else {
number1 = s.pop();
number2 = s.pop();
switch(c) {
case '+':
result = number1 + number2;
break;
case '-':
result = number1 - number2;
break;
case '*':
result = number1 * number2;
break;
case '/':
result = number1 / number2;
break;
} s.push(result);
}
System.out.println(result);
}
return s.pop();
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
String y = new String("(z * j)/(b * 8) ^2");
String x = new String("2 3 + 9 *");
TestingClass clas = new TestingClass(st);
clas.test(y);
clas.PostfixEvaluate(x);
}
}
This is the Stack Class:
public class Stacked {
int top;
char stack[];
int maxLen;
public Stacked(int max) {
top = -1;
maxLen = max;
stack = new char[maxLen];
}
public void push(int result) {
top++;
stack[top] = (char)result;
}
public int pop() {
int x;
x = stack[top];
//top = top - 1;
top--;
return x;
}
public boolean isStackEmpty() {
if(top == -1) {
System.out.println("Stack is empty " + "Equation Good");
return true;
}
else
System.out.println("Equation is No good");
return false;
}
public void reset() {
top = -1;
}
public void showStack() {
System.out.println(" ");
System.out.println("Stack Contents...");
for(int j = top; j > -1; j--){
System.out.println(stack[j]);
}
System.out.println(" ");
}
public void showStack0toTop() {
System.out.println(" ");
System.out.println("Stack Contents...");
for(int j=0; j>=top; j++){
System.out.println(stack[j]);
}
System.out.println(" ");
}
}
It looks to me like you aren't handling spaces at all.
This means that when you put in a space, it is implicitly converting the character space to the ascii value of it (32) when it pops it off the stack during an operation. Also, it looks like you are assuming that all numbers/results will be single digit, and casting from char to int, which is not what you want to do, since that will convert the char to the ascii value of the char, ' ' -> 32, '3' -> 51, etc.
If I were you, I would do this for your loop in PostfixEvaluate:
while(!e.equals("")){
string c;
int space = e.indexOf(' ');
if(space!=-1){
c = e.substring(0,space);
e = e.substring(space+2);
} else{
c = e;
e = "";
}
if (!c.equals("+")&& !c.equal("*") && !c.equals("-") && !c.equals("/")) {
//...
}
and change your stack to hold strings or ints.
The problem is that you are pushing char onto a stack as an int, so you are unintentionally working with the ascii representations of numbers, which is not the actual value of the number.
Instead of this complicated character walking, tokenize the input string using String.split(). Example:
String[] tokens = e.split(" ");
for(String token:tokens){
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
....
}
}
You need to split the string into tokens first:
/* Splits the expression up into several Strings,
* all of which are either a number or and operator,
* none of which have spaces in them. */
String [] expressionAsTokens = e.split(" ");
Then you need to make sure you compare Strings, not chars:
//compare strings instead of chars
String token = expressionAsTokens[j];
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
//same code as you had before
}
Also, is there any reason you are storing everything as a char array in your Stacked class? Your pop() method returns and integer, yet everything is stored as a char.
For this application, everything should be stored as an integer:
public class Stacked {
int stack[]; // array is of type integer
int top;
int maxLen;
// constructor
public void push() {/*...*/}
public int pop() {/*...*/} //pop returns an int as before
//...
}
One final note: Be careful what order you add and subtract the numbers in. I don't remember if postfix operands are evaluated left first or right first, but make sure you get them in the right order. As you have it now, 2 3 - 4 * would evaluate as 4 * (3 - 2) and I think it should be (2 - 3) * 4. This won't matter with adding and multiplying, but it will with subtracting and dividing.

Categories