Java - convert char input (representing Roman Numeral) to decimal equivalent - java

as the title suggests I am writing a simple prog using methods, that converts the char input of a Roman Numeral between ("M", "D", "C", "L", "X", "V", "I") And then printing the decimal equivalent.
I have written the program but it converts the decimal (int) to Roman Numeral
When modifying the program to accepts char input only to ("M", "D", "C", "L", "X", "V", "I") then outputting decimal, I get errors since char cannot be converted to int.
Any suggestions on how I would change this. Thanks
import java.util.Scanner;
class RomanNumeral {
public static String romanNumeralToInt(int romanNumeral) {
String Numeral = "";
int repeat;
int value[] = {1000, 500, 100, 50, 10, 5, 1 };
String symbol[] = {"M", "D", "C", "L", "X", "V", "I" };
for(int x = 0; romanNumeral > 0; x++) {
repeat = romanNumeral / value[x];
for(int i = 1; i <= repeat; i++) {
Numeral = Numeral + symbol[x];
}
romanNumeral = romanNumeral % value[x];
}
return Numeral;
}
public static void main(String args[]){
Scanner input = new Scanner(System.in);
final String INVALID = "Invalid number, try again!";
final int VALIDATE_NUMBER_1 = 1;
final int VALIDATE_NUMBER_5 = 5;
final int VALIDATE_NUMBER_10 = 10;
final int VALIDATE_NUMBER_50 = 50;
final int VALIDATE_NUMBER_100 = 100;
final int VALIDATE_NUMBER_500 = 500;
final int VALIDATE_NUMBER_1000 = 1000;
while (true) {
System.out.print("Enter a number: ");
int inputValue = input.nextInt();
if (inputValue == VALIDATE_NUMBER_1) {
System.out.println(VALIDATE_NUMBER_1 + " = " + romanNumeralToInt(1));
}
else if (inputValue == VALIDATE_NUMBER_5) {
System.out.println(VALIDATE_NUMBER_5 + " = " + romanNumeralToInt(5));
}
else if (inputValue == VALIDATE_NUMBER_10) {
System.out.println(VALIDATE_NUMBER_10 + " = " + romanNumeralToInt(10));
}
else if (inputValue == VALIDATE_NUMBER_50) {
System.out.println(VALIDATE_NUMBER_50 + " = " + romanNumeralToInt(50));
}
else if (inputValue == VALIDATE_NUMBER_100) {
System.out.println(VALIDATE_NUMBER_100 + " = " + romanNumeralToInt(100));
}
else if (inputValue == VALIDATE_NUMBER_500) {
System.out.println(VALIDATE_NUMBER_500 + " = " + romanNumeralToInt(500));
}
else if (inputValue == VALIDATE_NUMBER_1000) {
System.out.println(VALIDATE_NUMBER_1000 + " = " + romanNumeralToInt(1000));
}
else {
System.out.println(INVALID);
}
}
}
}
UPDATE
Code modified as suggested from post, althought still has errors as String cannot be converted to Int. Any suggestions. Thank you
import java.util.Scanner;
class RomanTest {
public static int romanNumeralToInt(char romanNumeral) {
String Numeral = "";
int repeat;
int value[] = {1000, 500, 100, 50, 10, 5, 1 };
char symbol[] = {'M', 'D', 'C', 'L', 'X', 'V', 'I' };
for(char x = 0; romanNumeral > 0; x++) {
repeat = romanNumeral / value[x];
for(int i = 1; i <= repeat; i++) {
Numeral = Numeral + symbol[x];
}
romanNumeral = romanNumeral % value[x];
}
return Numeral;
}
public static void main(String args[]){
Scanner input = new Scanner(System.in);
final String INVALID = "Invalid number, try again!";
final char VALIDATE_CHAR_M = 'M';
final char VALIDATE_CHAR_D = 'D';
final char VALIDATE_CHAR_C = 'C';
final char VALIDATE_CHAR_L = 'L';
final char VALIDATE_CHAR_X = 'X';
final char VALIDATE_CHAR_V = 'V';
final char VALIDATE_CHAR_I = 'I';
while (true) {
System.out.print("Enter a number: ");
char inputValue = input.nextLine().charAt(0);
if (inputValue == VALIDATE_CHAR_M) {
System.out.println(VALIDATE_CHAR_M + " = " + romanNumeralToInt('M'));
}
else if (inputValue == VALIDATE_CHAR_D) {
System.out.println(VALIDATE_CHAR_D + " = " + romanNumeralToInt('D'));
}
else if (inputValue == VALIDATE_CHAR_C) {
System.out.println(VALIDATE_CHAR_C + " = " + romanNumeralToInt('C'));
}
else if (inputValue == VALIDATE_CHAR_L) {
System.out.println(VALIDATE_CHAR_L + " = " + romanNumeralToInt('L'));
}
else if (inputValue == VALIDATE_CHAR_X) {
System.out.println(VALIDATE_CHAR_X + " = " + romanNumeralToInt('X'));
}
else if (inputValue == VALIDATE_CHAR_V) {
System.out.println(VALIDATE_CHAR_V + " = " + romanNumeralToInt('V'));
}
else if (inputValue == VALIDATE_CHAR_I) {
System.out.println(VALIDATE_CHAR_I + " = " + romanNumeralToInt('I'));
}
else {
System.out.println(INVALID);
}
}
}
}

First of all you should pay attention public static int romanNumeralToInt(char romanNumeral) it should return int, but you are returning String Numeral = ""; - it's String, Java as C# is strongly typed language, so you have to return String.
Second: concatenating String in way you are doing
for(int i = 1; i <= repeat; i++) {
Numeral = Numeral + symbol[x];
}
is not recommended (too slow, String is immutable so on every concatenation you are creating new String). Better approach is to use StringBuilder.
I've modified your code and came with something like :
private String decimalToRoman(int number) {
String[] romans = {"M", "CM", "D", "C", "XC", "L", "X", "IX", "V", "I"};
int[] values = {1000, 900, 500, 100, 90, 50, 10, 9, 5, 1};
StringBuilder builder = new StringBuilder();
for (int i = 0; i < values.length; i++) {
int times= number / values[i];
if (times== 0) {
continue;
}
if (times == 4 && i > 0) {
builder.append(romans[i]);
builder.append(romans[i - 1]);
} else {
for (int ii = 0; ii < times; ii ++) {
builder.append(romans[i]);
}
}
number = number % values[i];
}
return builder.toString();
}

You are doing very things in the wrong way. Here is one way to do.
class RomanNumeral {
public static void romanNumeralToInt(String romanNumeral) {
Map<Character,Integer> mapping = new HashMap<>();
mapping.put('M',1000);
mapping.put('D',500);
mapping.put('C',100);
mapping.put('L',50);
mapping.put('X',10);
mapping.put('V',5);
mapping.put('I',1);
int result = 0;
for(char each : romanNumeral.toCharArray()){
if(mapping.containsKey(each)){
result += mapping.get(each);
}
else{
System.out.println("Invalid number");
return;
}
}
System.out.println(result);
}
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a number: ");
String inputValue = input.nextLine();
romanNumeralToInt(inputValue);
}
}

The code in the main method already just accept the values 1000, 500, 100, 50, 10, 5, 1. Then in your romanNumeralToInt, there is some operations which are not necessary. Because you already have two arrays mapping for example 1 to I or 5 to V. If you find the index of 1 in the int array then your roman numeral is symbol[foundIndex]. I did not get the the purpose of those two for loops.
I get errors since char cannot be converted to int.
char can be converted to int. But "M" is not char, it is a String. 'M' is a char.
You can get a char from the user in the following way:
char charValue = input.nextLine().charAt(0);

Related

BaseConversion using Strings and bases 2 - 36

I have a program that prompts the user for a string, an initial base, and a final base. The program works fine for all digits however, when I enter in a string mixed with digits and characters it does not return the correct answer. For example, when I input the string BDRS7OPK48DAC9TDT4, original base: 30, newBase: 36, it should return ILOVEADVANCEDJAVA, but instead I get ILOVEADVANHSC6LTS. I know it's a problem with my algorithm but I cant figure out why it's returning the incorrect conversion.
import java.util.Scanner;
public class BaseConversion {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String theValue;
String result;
String newNum;
int initialBase;
int finalBase;
String[] parts = args;
if (parts.length > 0) {
theValue = parts[0];
isValidInteger(theValue);
initialBase = Integer.parseInt(parts[1]);
finalBase= Integer.parseInt(parts[2]);
isValidBase(finalBase);
}
else {
System.out.println("Please enter a value: ");
theValue = s.nextLine();
isValidInteger(theValue);
System.out.println("Please enter original base: ");
initialBase = s.nextInt();
System.out.println("Please enter new base: ");
finalBase = s.nextInt();
isValidBase(finalBase);
}
// check it
// isValidInteger(theValue, finalBase);
s.close();
newNum = convertInteger(theValue, initialBase, finalBase);
System.out.println("new number: " + newNum);
}
public static void isValidBase(int finalBase) {
if (finalBase < 2 || finalBase > 36) {
System.out.println("Error: Base must be greater than or equal to 2 & less than or equal to 36");
System.exit(1);
}
}
public static void isValidInteger(String num) {
char chDigit;
num = num.toUpperCase();
for(int d = 0; d < num.length(); d++) {
chDigit = num.charAt(d);
if (!Character.isLetter(chDigit) && !Character.isDigit(chDigit)) {
//System.out.println(chDigit);
System.out.println("Error character is not a letter or number");
System.exit(1);
}
}
}
public static String convertInteger(String theValue, int initialBase, int finalBase) {
double val = 0;
double decDigit = 0;
char chDigit;
// loop through each digit of the original number
int L = theValue.length();
for(int p = 0; p < L; p++) {
// get the digit character (0-9, A-Z)
chDigit = Character.toUpperCase(theValue.charAt(L-1-p));
// get the decimal value of our character
if(Character.isLetter(chDigit)) {
decDigit = chDigit - 'A' + 10;
}
else if (Character.isDigit(chDigit)) {
decDigit = chDigit - '0';
}
else {
System.out.println("Error d");
System.exit(1);
}
// add value to total
val += decDigit * Math.pow(initialBase, p);
}
// determine number of digits in new base
int D = 1;
for( ; Math.pow(finalBase, D) <= val; D++) {}
// use char array to hold new digits
char[] newNum = new char[D];
double pwr;
for(int p = D-1; p >= 0; p--) {
// calculate the digit for this power of newBase
pwr = Math.pow(finalBase, p);
decDigit = Math.floor(val / pwr);
val -= decDigit*pwr;
// store the digit character
if(decDigit <= 9) {
newNum[D - 1 - p] = (char) ('0' + (int)decDigit);
}
else {
newNum[D - 1 - p] = (char) ('A' + (int)(decDigit - 10));
}
}
return new String(newNum);
}
}
The algorithm is correct. Take a closer look instead at the place where you convert the input value to a decimal system and in particular at the limitations of the data type you are using.
Resources that could be helpful:
primitive data types - double point in the list
Floating point arithmetic
Question concerning similar problem
JLS - 4.2.3. Floating-Point Types, Formats, and Values
Hope this points you to the right track.
import java.math.BigInteger;
import java.util.Scanner;
public class BaseConversion {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String theValue;
String result;
String newNum;
int initialBase;
int finalBase;
String[] parts = args;
if (parts.length > 0) {
theValue = parts[0];
isValidInteger(theValue);
initialBase = Integer.parseInt(parts[1]);
finalBase= Integer.parseInt(parts[2]);
isValidBase(finalBase);
}
else {
System.out.println("Please enter a value: ");
theValue = s.nextLine();
isValidInteger(theValue);
System.out.println("Please enter original base: ");
initialBase = s.nextInt();
System.out.println("Please enter new base: ");
finalBase = s.nextInt();
isValidBase(finalBase);
}
// check it
// isValidInteger(theValue, finalBase);
s.close();
newNum = convertInteger(theValue, initialBase, finalBase);
System.out.println("new number: " + newNum);
}
public static void isValidBase(int finalBase) {
if (finalBase < 2 || finalBase > 36) {
System.out.println("Error: Base must be greater than or equal to 2 & less than or equal to 36");
System.exit(1);
}
}
public static void isValidInteger(String num) {
char chDigit;
num = num.toUpperCase();
for(int d = 0; d < num.length(); d++) {
chDigit = num.charAt(d);
if (!Character.isLetter(chDigit) && !Character.isDigit(chDigit)) {
//System.out.println(chDigit);
System.out.println("Error character is not a letter or number");
System.exit(1);
}
}
}
public static String convertInteger(String theValue, int initialBase, int finalBase) {
BigInteger bigInteger = new BigInteger(theValue,initialBase);
String value = bigInteger.toString(finalBase);
value = value.toUpperCase();
return value;
}
}
Here is the correct solution. The problem was with the data type not the algorithm. I hope this helps anyone dealing with the same type of problem.

Trying to pass around a String but receiving "null"

This is probably a simple error that I am over looking but my problem is that when I am trying to return the string "roman", it just returns null.
This is the main program:
/* CCTPG-22 // Assignment 08: Roman Numerals
* #author Kevin R. Trujillo
* #version 10/28/2015
* Purpose: Converts numbers into roman numerals format and vice-a-versa
* Status:
*/
import java.util.*; // For Scanner
public class RomanMain
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
RomanYear year1 = new RomanYear(1975);
RomanYear year2 = new RomanYear(1988);
RomanYear year3 = new RomanYear(2007);
System.out.println(year1.toString());
System.out.println(year2.toString());
System.out.println(year3.toString());
int diff21 = year2.getYearDecimal() - year1.getYearDecimal();
int diff32 = year3.getYearDecimal() - year2.getYearDecimal();
RomanYear y2MinusY1 = new RomanYear(diff21);
RomanYear y3MinusY2 = new RomanYear(diff32);
System.out.println("Year2 minus Year1 is: " + y2MinusY1.getYearRoman());
System.out.println("Year3 minus Year2 is: " + y3MinusY2.getYearRoman());
}
// Add new methods here
} // No code can be here (outside the class)
and here is the RomanYear class:
/**
* Auto Generated Java Class.
*/
public class RomanYear {
private int decimal ;
private String roman ;
public RomanYear() // default constructor
{
decimal = 0 ;
roman = "" ;
}
public RomanYear(int newYear)
{
decimal = newYear ;
roman = setYearDecimal(decimal);
}
public RomanYear(String newYear )
{
roman = newYear ;
decimal = setYearRoman(roman) ;
}
public int setYearRoman(String roman)
{
String romanNumeral = roman.toUpperCase();
for(int x = 0;x < romanNumeral.length(); x++)
{
char convertToDecimal = roman.charAt(x);
// first step: Easy stuff
switch (convertToDecimal)
{
case 'M': decimal += 1000; break;
case 'D': decimal += 500; break;
case 'C': decimal += 100; break;
case 'L': decimal += 50; break;
case 'X': decimal += 10; break;
case 'V': decimal += 5; break;
case 'I': decimal += 1; break;
}
}
// Now adapt for specials
if (romanNumeral.contains("IV"))
{
decimal-=2;
}
if (romanNumeral.contains("IX"))
{
decimal-=2;
}
if (romanNumeral.contains("XL"))
{
decimal-=20;
}
if (romanNumeral.contains("XC"))
{
decimal-=20;
}
if (romanNumeral.contains("CD"))
{
decimal-=200;
}
if (romanNumeral.contains("CM"))
{
decimal-=200;
}
return decimal ;
}
public String setYearDecimal(int yr)
{
if (decimal > 3999)
{
System.out.println("Decimal Number: " + decimal + " is over 3999. ") ;
System.out.println("Please enter a new number") ;
System.out.println("Program is ending.............") ;
try {
Thread.sleep(2000); //5000 milliseconds is one second.
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.exit(0) ;
}
else
{
int digit;
String roman = "";
// 1000's column
digit = yr/1000;
for (int i = 0; i < digit; i++)
roman = roman + "M";
yr = yr % 1000; // leaves 0 to 999
// 100s column
String [] hunds = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
digit = yr/100;
roman = roman + hunds[digit];
yr = yr % 100; // leaves 0 to 99
// 10s column
String [] tens = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
digit = yr/10;
roman = roman + tens[digit];
yr = yr % 10; // leaves 0 to 9
// Ones column
String [] ones = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
roman = roman + ones[yr];
}
return roman ;
}
public int getYearDecimal()
{
return decimal ;
}
public String getYearRoman()
{
return roman ;
}
public String toString()
{
System.out.print("Decimal: " + decimal + " as Roman Numerals is " ) ;
return roman ;
}
/* ADD YOUR CODE HERE */
}
If someone could just explain what I am doing wrong, that would be much appreciated rather than just posting the "correct way" to do it.
Thank you!
On the top of the Roman class you create a variable called roman.
public class RomanYear {
private int decimal ;
private String roman ;
In setYearDecimal you create a new variable called roman. That local variable hides the global one.
int digit;
String roman = "";
When you do roman = roman + "M"; you are only updating the local roman variable. The global one remains empty.
All you need to do is remove String from in front of the second variable.

Java String Calculator

I'm trying to make a simple calculator in Java which takes input in the form of a string and does a simple '+' and '-' operation.
Single digit inputs work but my problem is when i try to implement this for double digit
input string is: 5+20+5+11
list 1 = [5, 20, 2, 0, 5, 11, 1]
list 2 = [+, +, +]
Answer:27
I need to find a way where after storing [5] in list1 how i can add [5,20] instead of [5,20,2,0] which the current code is doing.
public int calC(String input) {
int len = input.length();
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
for (int i = 0; i < len; i++) {
if ((input.charAt(i) != '+') && (input.charAt(i) != '-')) {
// check if the number is double-digit
if ((i + 1 <= len - 1)) {
if ((input.charAt(i + 1) != '+')&& (input.charAt(i + 1) != '-')) {
String temp = "";
temp = temp + input.charAt(i) + input.charAt(i + 1);
int tempToInt = Integer.parseInt(temp);
// adding the double digit number
list1.add(tempToInt);
}
// add single digit number
list1.add(input.charAt(i) - '0');
}
} else {
// adding the symbols
list2.add(input.charAt(i));
}
}
int result = 0;
result = result + (int) list1.get(0);
for (int t = 0; t < list2.size(); t++) {
char oper = (char) list2.get(t);
if (oper == '+') {
result = result + (int) list1.get(t + 1);
} else if (oper == '-') {
result = result - (int) list1.get(t + 1);
}
}
return result;
}
Edit: working version
#Ker p pag thanks for the updated methods
input string is: 5+20+5+11
[5, 20, 5, 11]
[+, +, +]
Answer:41
I'll need to try to implement this with stack as suggested but the current version works
static boolean isDigit(char check) {
if (Character.isDigit(check)) {
return true;
}
return false;
}
public static int calC(String input) {
int len = input.length();
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
for (int i = 0; i < len; i++) {
if ((i + 1 <= len - 1)) {
if (isDigit(input.charAt(i)) && isDigit(input.charAt(i + 1))) {
String temp = input.charAt(i) + "" + input.charAt(i + 1);
int toInt = Integer.parseInt(temp);
list1.add(toInt);
i = i+1;
} else if (isDigit(input.charAt(i))) {
list1.add(input.charAt(i)- '0');
} else {
list2.add(input.charAt(i));
}
}
}
int result = 0;
result = result + (int) list1.get(0);
for (int t = 0; t < list2.size(); t++) {
char oper = (char) list2.get(t);
if (oper == '+') {
result = result + (int) list1.get(t + 1);
} else if (oper == '-') {
result = result - (int) list1.get(t + 1);
}
}
return result;
}
Here is the code:
String a = "5+20-15+8";
System.out.println(a);
String operators[]=a.split("[0-9]+");
String operands[]=a.split("[+-]");
int agregate = Integer.parseInt(operands[0]);
for(int i=1;i<operands.length;i++){
if(operators[i].equals("+"))
agregate += Integer.parseInt(operands[i]);
else
agregate -= Integer.parseInt(operands[i]);
}
System.out.println(agregate);
If you want the result 41 for input string "5+20+5+11",
why not use ScriptEngineManager with JavaScript engine,
public double calC(String input) {
int result = 0;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
return (Double)engine.eval(input);
}
But note that the return type is double here.
If you want only int as return type in this case, try with this
return new BigDecimal(engine.eval(input).toString()).intValue();
Another way to think about this:
public class InlineParsing {
public static void main(String []args){
String input = "5-2+20+5+11-10";
input = input.replace(" ","");
String parsedInteger = "";
String operator = "";
int aggregate = 0;
for (int i = 0; i < input.length(); i++){
char c = input.charAt(i);
if (Character.isDigit(c)) {
parsedInteger += c;
}
if (!Character.isDigit(c) || i == input.length()-1){
int parsed = Integer.parseInt(parsedInteger);
if (operator == "") {
aggregate = parsed;
}
else {
if (operator.equals("+")) {
aggregate += parsed;
}else if (operator.equals("-")){
aggregate -= parsed;
}
}
parsedInteger ="";
operator = ""+c;
}
}
System.out.println("Sum of " + input+":\r\n" + aggregate);
}
}
It's basically a state machine that traverses over each char.
Iterate over each char:
if current char is a digit, add to current number buffer
if current char is not a digit or we're parsing the last digit
if an operator has been parsed use that to add the newly parsed number to the sum
if no operator has been parsed, set sum to current parsed number
clear current number buffer
store current char as operator
I agree that stack is the best solution,but still giving an alternative way
of doing this.
String input = "5+20+11+1";
StringBuilder sb = new StringBuilder();
List<Integer> list1 = new ArrayList<Integer>();
List<Character> list2 = new ArrayList<Character>();
char[] ch = input.toCharArray();
for(int i=0;i<ch.length;i++)
{
if(ch[i]!='+')
{
sb.append(ch[i]);
}else
{
list2.add(ch[i]);
list1.add(Integer.valueOf(sb.toString()));
sb.setLength(0);
}
}
if(sb.length()!=0)
list1.add(Integer.valueOf(sb.toString()));
System.out.println(list1.size());
for(Integer i:list1)
{
System.out.println("values"+i);
}
for storing the input to the list you could try this snippet
for (int i = 0; i < input.length() - 1; i++) {
// make a method
// check if current character is number || check if current
// character is number and the next character
if (isDigit(input.charAt(i)) && isDigit(input.charAt(i + 1))) {
list.add(input.charAt(i) +""+ input.charAt(i + 1));
} else if (isDigit(input.charAt(i))) {
list.add(input.charAt(i));
}else{
operator.add(input.charAt(i));
}
}
//check if it is a number
public boolean isDigit(char input){
if(input == '1' ||
input == '2' ||
input == '3' ||
input == '4' ||
input == '5' ||
input == '6' ||
input == '7' ||
input == '8' ||
input == '9' ||
input == '0')
return true;
return false;
}
I could advise you to use Exp4j. It is easy to understand as you can see from the following example code:
Expression e = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.variables("x", "y")
.build()
.setVariable("x", 2.3)
.setVariable("y", 3.14);
double result = e.evaluate();
Especially for the case of using more complex expression this could be a better choice.
private static int myCal() {
String[] digits = {
"1",
"2",
"3",
"4",
"5"
};
String[] ops = {
"+",
"+",
"+",
"-"
};
int temp = 0;
int res = 0;
int count = ops.length;
for (int i = 0; i < digits.length; i++) {
res = Integer.parseInt(digits[i]);
if (i != 0 && count != 0) {
count--;
switch (ops[i - 1]) {
case "+":
temp = Math.addExact(temp, res);
break;
case "-":
temp = Math.subtractExact(temp, res);
break;
case "*":
temp = Math.multiplyExact(temp, res);
break;
case "/":
temp = Math.floorDiv(temp, res);
break;
}
}
}
return temp;
}
You can check this code that I created using array only. I also tried several arithmetic problems also your given problem.
Please see also the comments within the method.
public static String Calculator(String str) {
// will get all numbers and store it to `numberStr`
String numberStr[] = str.replaceAll("[+*/()-]+"," ").split(" ");
// will get all operators and store it to `operatorStr`
String operatorStr[] = str.replaceAll("[0-9()]+","").split("");
int total = Integer.parseInt(numberStr[0]);
for (int i=0; i<operatorStr.length; i++) {
switch (operatorStr[i]) {
case "+" :
total += Integer.parseInt(numberStr[i+1]);
break;
case "-" :
total -= Integer.parseInt(numberStr[i+1]);
break;
case "*" :
total *= Integer.parseInt(numberStr[i+1]);
break;
case "/" :
total /= Integer.parseInt(numberStr[i+1]);
break;
}
if(i+2 >= operatorStr.length) continue; // if meets the last operands already
numberStr[i+1] = String.valueOf(total);
}
return String.valueOf(total);
}
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
ArrayList<Character> listOfOpertionsCharFORM = new ArrayList<>();
ArrayList<Character> listOfNumbersCharFORM = new ArrayList<>();
ArrayList<Integer> listOfNumbersINTEGERFORM = new ArrayList<>();
int Total = 0;
Scanner sc = new Scanner(System.in);
String input;
System.out.print("Please enter your math equation :");
input = sc.nextLine();
System.out.println("string is : " + input);
separator();
char[] convertAllToChar = input.toCharArray();
for (char inputToChar : convertAllToChar) {
System.out.println("convertAllToChar " + inputToChar);
}
for (int i = 0; i < input.length(); i++) {
if (convertAllToChar[i] == '+') {
listOfOpertionsCharFORM.add(convertAllToChar[i]);
}
if (convertAllToChar[i] == '-') {
listOfOpertionsCharFORM.add(convertAllToChar[i]);
}
if (convertAllToChar[i] == '*') {
listOfOpertionsCharFORM.add(convertAllToChar[i]);
}
if (convertAllToChar[i] == '/') {
listOfOpertionsCharFORM.add(convertAllToChar[i]);
}
if (Character.isDigit(convertAllToChar[i])) {
listOfNumbersCharFORM.add(convertAllToChar[i]);
}
}
separator();
for (Character aa : listOfOpertionsCharFORM) {
System.out.println("list Of Operations Char FORM " + aa);
}
separator();
for (Character aa : listOfNumbersCharFORM) {
System.out.println("list Of Numbers Char FORM " + aa);
}
separator();
for (Character aa : listOfNumbersCharFORM) {
if (aa == '0') listOfNumbersINTEGERFORM.add(0);
if (aa == '1') listOfNumbersINTEGERFORM.add(1);
if (aa == '2') listOfNumbersINTEGERFORM.add(2);
if (aa == '3') listOfNumbersINTEGERFORM.add(3);
if (aa == '4') listOfNumbersINTEGERFORM.add(4);
if (aa == '5') listOfNumbersINTEGERFORM.add(5);
if (aa == '6') listOfNumbersINTEGERFORM.add(6);
if (aa == '7') listOfNumbersINTEGERFORM.add(7);
if (aa == '8') listOfNumbersINTEGERFORM.add(8);
if (aa == '9') listOfNumbersINTEGERFORM.add(9);
}
for (Integer aaa : listOfNumbersINTEGERFORM) {
System.out.println("list Of Numbers INTEGER FORM " + aaa);
}
separator();
separator();
separator();
System.out.print(listOfNumbersINTEGERFORM);
System.out.print(listOfOpertionsCharFORM);
System.out.println();
System.out.println();
if (listOfNumbersINTEGERFORM.size() == (listOfOpertionsCharFORM.size() + 1)) {
for (int i = 0; i < listOfOpertionsCharFORM.size(); i++) {
System.out.println("i :" + i);
if (listOfOpertionsCharFORM.get(i) == '+') if (i == 0) {
Total = Total + listOfNumbersINTEGERFORM.get(i) + listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
} else {
Total = Total + listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
}
if (listOfOpertionsCharFORM.get(i) == '-') if (i == 0) {
Total = Total + listOfNumbersINTEGERFORM.get(i) - listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
} else {
Total = Total - listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
}
if (listOfOpertionsCharFORM.get(i) == '*') if (i == 0) {
Total = Total + listOfNumbersINTEGERFORM.get(i) * listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
} else {
Total = Total * listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
}
if (listOfOpertionsCharFORM.get(i) == '/') if (i == 0) {
Total = Total + listOfNumbersINTEGERFORM.get(i) / listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
} else {
Total = Total / listOfNumbersINTEGERFORM.get(i + 1);
System.out.println("total : " + Total);
separatorShort();
}
}
} else {
System.out.println("*********###############**********");
System.out.println("** your input not correct input **");
System.out.println("*********###############**********");
}
System.out.println("*** Final Answer *** : " + Total);
}
public static void separator() {
System.out.println("___________________________________");
}
public static void separatorShort() {
System.out.println("_____________");
}

RSA Encryption Not encrypting correctly

I am attempting to create my first public key encryption program an have recently tested the encryption section of code unsuccessfully. This is probably a very simple error, but bear with me for a moment. I have tried encrypting the word "hello" and the program return the translation of [D#34005e1, multiple times. Below is the code for my classes, any help would be appreciated.
Main:
package MAE;
import java.util.Scanner;
import java.lang.Math;
public class Main
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
int choice;
boolean exit = true;
while(exit == true)
{
System.out.println("Please select a option from the menu below.");
System.out.println("1. Generate Key");
System.out.println("2. Encrypt Message");
System.out.println("3. Decrypt Message");
System.out.println("4. Exit");
choice = Input.nextInt();
switch(choice)
{
case 1:
keyGen();
break;
case 2:
encrypt();
break;
case 3:
decrypt();
break;
case 4:
exit = false;
break;
}
}
}
public static void keyGen()
{
Scanner Input = new Scanner(System.in);
encryptionAlgorithm eKey = new encryptionAlgorithm();
System.out.println("Public Key-(" + eKey.getDValue() + ", " + eKey.getNValue() + ")");
System.out.println("Private Key-(" + eKey.getEValue() + ", " + eKey.getNValue() + ")");
}
public static void encrypt()
{
String alphabet[] = new String[] {"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", ".", " "};
Scanner Input =new Scanner(System.in);
System.out.println("Enter Encryption Key First Digit:");
double eKey1 = Input.nextDouble();
System.out.println("Enter Encryption Key Second Digit");
double eKey2 = Input.nextDouble();
Input.nextLine();
System.out.println("Enter message to Encrypt, omitting any puncuation besides periods.");
String message = Input.nextLine();
String messageChars[] = new String[message.length()];
int messageValues[] = new int[message.length()];
double previousValue = 0;
double messageEncrypted[] = new double[message.length()];
double tempval = 0;
for(int x = 0; x < message.length(); x++)
{
messageChars[x] = Character.toString(message.charAt(x));
}
for(int x = 0; x < message.length(); x++)
{
for(int y = 0; y < alphabet.length; y++)
{
if(messageChars[x].equals(alphabet[y]))
{
messageValues[x] = y;
}
}
}
for(int x = 0; x < messageValues.length; x++)
{
previousValue = (messageValues[x] - 1 * messageValues[x] + 1) % messageValues[x];
tempval = Math.pow(messageValues[x], eKey1);
messageEncrypted[x] = (tempval % eKey2) + previousValue;
}
for(int x = 0; x < messageEncrypted.length; x++)
{
System.out.println(messageEncrypted + ", ");
}
}
public static void decrypt()
{
}
}
encryptionAlgorithm:
package MAE;
import java.util.Scanner;
import java.util.Random;
public class encryptionAlgorithm
{
public static double p;
public static double q;
public static double n;
public static double r;
public static double k;
public static double eKey;
public static double dKey;
public encryptionAlgorithm()
{
Random random = new Random();
boolean isPPrime = true;
boolean isQPrime = true;
double d = 2;
Scanner Input = new Scanner(System.in);
System.out.println("Please enter a prime number. Larger numbers are more secure.");
p = Input.nextDouble();
do
{
isPPrime = true;
for(d = 2; d * d <= p && isPPrime == true; d++)
{
if(p % d == 0)
{
isPPrime = false;
}
}
if(isPPrime == false)
{
System.out.println("This number is not prime. Please enter another number.");
p = Input.nextDouble();
}
} while(isPPrime == false);
d = 2;
System.out.println("Please enter another prime number. Larger numbers are more secure.");
q = Input.nextDouble();
do
{
while(q == p)
{
System.out.println("This number is identical to the first entered number. Please enter another number.");
q = Input.nextDouble();
}
isQPrime = true;
for(d = 2; d * d <= q && isQPrime == true; d++)
{
if(q % d == 0)
{
isQPrime = false;
}
}
if(isQPrime == false)
{
System.out.println("This number is not prime. Please enter another number.");
q = Input.nextDouble();
}
} while(isQPrime == false);
n = p * q;
r = (p - 1) * (q - 1);
double x = r + 1;
float v = 2;
while(k == 0)
{
while(v * v <= x)
{
if(x % v == 0)
{
k = x;
}
v++;
}
x += r;
}
k += r * random.nextInt(3);
for(int c = 2; c <= k; c++)
{
if(k % c == 0)
{
eKey = c;
dKey = k/eKey;
}
}
}
public double getPValue()
{
return p;
}
public double getQValue()
{
return q;
}
public double getNValue()
{
return n;
}
public double getRValue()
{
return r;
}
public double getKValue()
{
return k;
}
public double getEValue()
{
return eKey;
}
public double getDValue()
{
return dKey;
}
}
This code is fundamentally wrong. First of all you cant use doubles. Doubles are not capable of holding more than 64 bits of information, and lose information when you perform operations such as power, when the number overflows.Also you use signed integers, so at best you can have RSA31 which is absolutely useless and can be broken in a microsecond. But even to use RSA31 you should perform modular exponent, which is not exponent followed by a modulo, because for real RSA when you use large numbers, 1024 bits for say, the result of an exponent would be 2^100 bit, not something your computer can store. In your usage with integers, the result of the exponent also easily overflows.
There are other problems in your code, but first you some multi-precision integer library, with modular exponentiation.

Amicable numbers Java program

So I am having this strange output in which only the first number is checked twice while the second number is not even considered.Please help.
Code :-
import java.util.Scanner;
public class Amicable
{
private static int a,b;
private static String m,n;
public static void main()
{
acceptNumbers();
if (firstNumber() == secondNumber())
{
System.out.println(a+" and "+b+" are amicable numbers");
}
else System.out.println(a+" and "+b+" are not amicable numbers");
}
public static void acceptNumbers()
{
Scanner sc = new Scanner(System.in);
int count=0;
System.out.print("Enter two numbers [ separated by a ',' ] : ");
String input = sc.nextLine();
System.out.println();
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
if (c == ',')
{
count++;
if (count == 1)
{
m = input.substring(0,i);
n = input.substring(0,i);
}
break;
}
}
if (count == 0)
{
System.out.println("Invalid operation : You have entered only 1 number");
}
m = m.trim(); n = n.trim();
a = Integer.valueOf(m);
b = Integer.valueOf(n);
}
public static int firstNumber()
{
int a1,a2=0;
for (int i = 0; i < m.length()-1; i++)
{
a1 = Integer.valueOf(m.charAt(i));
if (a%a1 == 0) a2 = a2+a1;
}
return a2;
}
public static int secondNumber()
{
int b1,b2=0;
for (int i = 0; i < n.length()-1; i++)
{
b1 = Integer.valueOf(n.charAt(i));
if (b%b1 == 0) b2 = b2+b1;
}
return b2;
}
}
And here is the output :-
Enter 2 numbers [ separated by a ',' ] : 248 , 222
248 and 248 are amicable numbers
your m and n are equal, because you have:
m = input.substring(0,i);
n = input.substring(0,i);
change it to:
m = input.substring(0,i);
n = input.substring(i+1);
Btw you are doing a lot of unnecessary stuff, complete solution (I don't care about exceptions):
import java.util.Scanner;
public class Amicable {
public static void main(String args[]) {
try {
Scanner sc = new Scanner(System.in);
System.out.print("Enter two numbers [ separated by a ',' ] : ");
String input = sc.nextLine();
String[] numbers = input.split(",");
int num1 = Integer.parseInt(numbers[0].trim());
int num2 = Integer.parseInt(numbers[1].trim());
int sum1 = 0, sum2 = 0;
for (int i = 1; i <= num1; i++) {
if (num1 % i == 0)
sum1 += i;
}
for (int i = 1; i <= num2; i++) {
if (num2 % i == 0)
sum2 += i;
}
if (sum1 == sum2)
System.out.println(num1 + " and " + num2
+ " are amicable numbers");
else
System.out.println(num1 + " and " + num2
+ " are not amicable numbers");
} catch (Exception e) {
e.printStackTrace();
}
}
}
parts of code from: http://www.daniweb.com/software-development/java/code/304600/amicable-numbers
a and b are derived from m and n, and the latter are initialized to exactly the same value:
m = input.substring(0,i);
n = input.substring(0,i);
Did you mean to set n to
n = input.substring(i+1);
?
m = input.substring(0,i);
n = input.substring(0,i);
m and n are having the same value.
n should be:
n = input.substring(i+1);
And now the second number will be assigned to n.

Categories