Validation of Roman Numerals! (Java) - java

I have written a Java program to convert roman numerals into numbers. My only problem is if somebody enters "IIII" it shows up as 4, but instead it should give an error that it is not a valid roman numeral. I need to include the following rules into my code. Could anybody help me with this?
(1) No digit is repeated in succession more than thrice, i.e., I, X and C cannot be repeated more than 3 times.
(2) The digits V, L and D are not repeated. The repetition of V, L and D is invalid in the formation of numbers.

Conversion of Roman number to Decimal number:
public class RomanNumberUtils {
static String romanNumeral;
static int decimalNum;
public static void main(String args[]) {
RomanNumberUtils roman = new RomanNumberUtils();
roman .convertRomanToDecimal();
roman .printRoman(romanNumeral);
}
public void convertRomanToDecimal () {
Scanner scan = new Scanner(System.in);
System.out.print("Enter a Roman number: ");
romanNumeral = scan.nextLine();
romanNumeral = romanNumeral.toUpperCase();
int l= romanNumeral.length();
int num=0;
int previousnum = 0;
for (int i=l-1;i>=0;i--)
{
char x = romanNumeral.charAt(i);
x = Character.toUpperCase(x);
switch(x)
{
case 'I':
previousnum = num;
num = 1;
break;
case 'V':
previousnum = num;
num = 5;
break;
case 'X':
previousnum = num;
num = 10;
break;
case 'L':
previousnum = num;
num = 50;
break;
case 'C':
previousnum = num;
num = 100;
break;
case 'D':
previousnum = num;
num = 500;
break;
case 'M':
previousnum = num;
num = 1000;
break;
}
if (num<previousnum)
{decimalNum= decimalNum-num;}
else
decimalNum= decimalNum+num;
}
}
public static void printRoman (String romanNumeral){
System.out.println ("The equivalent of the Roman numeral "+romanNumeral+" is "+decimalNum);
}
}

Here's my version of a Roman numeral to decimal number converter.
Here are the test results from one of my many tests.
Enter a Roman numeral: ccccllllxxxxvvvviiii
The input Roman numeral CCCCLLLLXXXXVVVVIIII is invalid.
The correct Roman numeral is DCLXIV.
The decimal value is 664.
Enter a Roman numeral: mcmlxxii
The input Roman numeral MCMLXXII is valid.
The decimal value is 1972.
Enter a Roman numeral: mmmccclll
The input Roman numeral MMMCCCLLL is invalid.
The correct Roman numeral is MMMCDL.
The decimal value is 3450.
Enter a Roman numeral: mcmlxxio
The input Roman numeral MCMLXXIO contains invalid characters.
Enter a Roman numeral: lcl
The input Roman numeral LCL is invalid.
The correct Roman numeral is CC.
The decimal value is 200.
Enter a Roman numeral: quit
Basically, I converted the input Roman numeral into a decimal number. Then I converted the decimal number back into a Roman numeral. I compared the Roman numerals, and output the correct Roman numeral along with the decimal value.
Here's the complete runnable code.
import java.util.Scanner;
public class RomanNumeralConversion {
public static void main(String[] args) {
RomanNumeralConversion rnc = new RomanNumeralConversion();
rnc.processRomanNumerals();
}
private Object[][] conversion = { { 1000, 900, 500, 400, 100, 90,
50, 40, 10, 9, 5, 4, 1 },
{ "M", "CM", "D", "CD", "C", "XC", "L", "XL",
"X", "IX", "V", "IV", "I" } };
public void processRomanNumerals() {
Scanner scanner = new Scanner(System.in);
String inputRomanNumeral = readRomanNumeral(scanner);
while (!inputRomanNumeral.equals("QUIT")) {
int value = convertToDecimal(inputRomanNumeral);
if (value < 0) {
System.out.println("The input Roman numeral " +
inputRomanNumeral + " contains invalid characters.");
} else {
String calculatedRomanNumeral = convertToRoman(value);
if (inputRomanNumeral.equals(calculatedRomanNumeral)) {
System.out.println("The input Roman numeral " +
inputRomanNumeral + " is valid.");
} else {
System.out.println("The input Roman numeral " +
inputRomanNumeral + " is invalid.");
System.out.println("The correct Roman numeral is " +
calculatedRomanNumeral + ".");
}
System.out.println("The decimal value is " + value + ".");
}
inputRomanNumeral = readRomanNumeral(scanner);
}
scanner.close();
}
private String readRomanNumeral(Scanner scanner) {
System.out.print("Enter a Roman numeral: ");
return scanner.nextLine().trim().toUpperCase();
}
private int convertToDecimal(String input) {
int output = 0;
int index = 0;
while (index < input.length()) {
boolean isInvalid = true;
for (int i = 0; i < conversion[1].length; i++) {
String test = (String) conversion[1][i];
int j = index + test.length();
if ((j <= input.length()) &&
(input.substring(index, j).equals(test))) {
output += (Integer) conversion[0][i];
index = j;
isInvalid = false;
break;
}
}
if (isInvalid) {
return -1;
}
}
return output;
}
private String convertToRoman(int input) {
String output = "";
for (int i = 0; i < conversion[0].length; i++) {
int value = (Integer) conversion[0][i];
if (input >= value) {
output += (String) conversion[1][i];
input -= value;
i--;
}
}
return output;
}
}

Related

Build is successful but I kept getting the 'Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1'

I have 3 classes but I think the problems are occurring between the Main and the Roman Numerals class. . . would also include the class Variables as well. . .
import java.util.Scanner;
public class Main{
public static void main (String[] args){
System.out.println("Press 1 for RPS, 2 for Flowchart, 3 for Roman Numerals, 4 for Ascendant");
Scanner Selection = new Scanner(System.in);
Variables sel = new Variables();
sel.run = Selection.nextLine();
{
if (sel.run.equals("1")){
System.out.println("You have chosen and initialized 1!");
System.out.println("\nAttempting to Connect to RPS Class\n");
RPS JackEnPoy = new RPS();
JackEnPoy.RockPaperScissors();
}
else if (sel.run.equals("2")){
System.out.println("You have chosen and initialized 2!");
System.out.println("\nAttempting to Connect to Flowchart Class\n");
Flowchart chart = new Flowchart();
chart.Flow();
}
else if (sel.run.equals("3")){
System.out.println("You have chosen and initialized 3!");
System.out.println("\nAttempting to Connect to RomanNumerals Class\n");
RomanNumerals rn = new RomanNumerals();
rn.Numeral();
}
else if (sel.run.equals("4")){
System.out.println("You have chosen and initialized 4!");
System.out.println("\nAttempting to Connect to Ascending Class\n");
//Ascending aorder = new Ascending();
//aorder.Ascendant();
}
}
}
}
and the class variables for the other classes
class Variables{
String run;
//RPS
String guide;
String RW = "Rock Smashes Scissors!";
String PW = "Paper Covers Rock!";
String SW = "Scissors Shreds Paper!";
String T = "Impasse!";
//Flowchart
int x;
int y;
int z;
boolean YN;
}
and this is the Roman Numerals that I've been currently trying to work on whilst the RPS(Rock Paper Scissors) class and Flowchart class worked fine
import java.util.Scanner;
import javax.swing.JOptionPane;
public class RomanNumerals{
public static void Numeral()
{
//Declarations
String num = " ", roman = " ";
char sen = num.charAt(0), hachi = num.charAt(1), jyu = num.charAt(2), ichi = num.charAt(3);
int convert;
//String from num to Integer
convert = Integer.parseInt(num);
num = JOptionPane.showInputDialog("Convert from Whole Numbers to Roman Numerals(Maximum:3000)");
//'if' more than 3k then terminate 'else' attempt conversion
if (convert > 3000)
{
//Invalid Message with WARNING_MESSAGE dialog
JOptionPane.showMessageDialog (null, "Input had exceeded the maximum of 3000", "RomanNumerals3000", JOptionPane.WARNING_MESSAGE);
}
else
{
if (ichi == '1')//0001
roman += "I";
if (ichi == '2')//0002
roman += "II";
if (ichi == '3')//0003
roman += "III";
if (ichi == '4')//0004
roman += "IV";
if (ichi == '5')//0005
roman += "V";
if (ichi == '6')//0006
roman += "VI";
if (ichi == '7')//0007
roman += "VII";
if (ichi == '8')//0008
roman += "VIII";
if (ichi == '9')//0009
roman += "IX";
if (jyu == '1')//0010
roman += "X";
if (jyu == '2')//0020
roman += "XX";
if (jyu == '3')//0030
roman += "XXX";
if (jyu == '4')//0040
roman += "XL";
if (jyu == '5')//0050
roman += "L";
if (jyu == '6')//0060
roman += "LX";
if (jyu == '7')//0070
roman += "LXX";
if (jyu == '8')//0080
roman += "LXXX";
if (jyu == '9')//0090
roman += "XC";
if (hachi == '1')//0100
roman += "C";
if (hachi == '2')//0200
roman += "CC";
if (hachi == '3')//0300
roman += "CCC";
if (hachi == '4')//0400
roman += "CD";
if (hachi == '5')//0500
roman += "D";
if (hachi == '6')//0600
roman += "DC";
if (hachi == '7')//0700
roman += "DCC";
if (hachi == '8')//0800
roman += "DCCC";
if (hachi == '9')//0900
roman += "CM";
if (sen == '1')//1000
roman += "M";
if (sen == '2')//2000
roman += "MM";
if (sen == '3')//3000
roman += "MMM";
JOptionPane.showMessageDialog(null, "Whole Number Form = " + num + "\nRoman Numeral Form = " + roman, "Converted!!!", JOptionPane.INFORMATION_MESSAGE,null);
}
System.exit(0);
}
}
and the output went on like this. .
3
You have chosen and initialized 3!
Attempting to Connect to RomanNumerals Class
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:48)
at java.base/java.lang.String.charAt(String.java:1512)
at RomanNumerals.Numeral(RomanNumerals.java:9)
at Main.main(Main.java:27)
Command execution failed.```
I'm still new here and can't figure out on why am I getting this error after initiating 3 as in the RomanNumerals class. .
char sen = num.charAt(0), hachi = num.charAt(1), jyu = num.charAt(2), ichi = num.charAt(3);
If the string is less than 4 characters long, this will crash because it doesn't know what to return for num.charAt(). You want to rewrite this so it only gets the characters if the length of the string is long enough.
So your problem looks like it's here:
String num = " ", roman = " ";
So at the point above you've initialized num to be a String with a single character, a space, in it.
char sen = num.charAt(0), hachi = num.charAt(1), jyu = num.charAt(2), ichi = num.charAt(3);
In the following line above, you are asking for the first ( char(0) cause string character indexing is zero-based in Java), second (char(1)), third (char(2)) and fourth (char(3)) characters.
This fails cause the string only has the single character.
Also, just because code compiles doesn't mean it will run successfully.

Number Conversion System in Java

import java.util.Scanner;
public class NumberConversionSystems {
public static void main(String[] args) {
//String binary = toBinaryString(number);
Scanner input = new Scanner(System.in);
System.out.println("Number Conversion Systems \n");
// Display the menu
System.out.println("1.\t Decimal to Binary");
System.out.println("2.\t Decimal to Hexadecimal");
System.out.println("3.\t Binary to Decimal");
System.out.println("4.\t Hexadecimal to Decimal \n");
System.out.println("Your choice?");
//Get user's choice
int choice = input.nextInt();
switch (choice) {
case 1: System.out.println("\nEnter Decimal Number");
break;
case 2: System.out.println("\nEnter Decimal Number");
break;
case 3: System.out.println("\nEnter Binary");
break;
case 4: System.out.println("\nEnter Hexadecimal");
break;
default:
System.out.println("\nInvalid choice. Please choose a number between 1 and 4.");
choice = input.nextInt();
break;
}
if (choice == 1) {
int number = input.nextInt();
String binary = toBinaryString(number);
binary = recursive(number);
System.out.printf("Decimal to Binary (%d) = %s", number, binary);
}
else if (choice == 2) {
int number2 = input.nextInt();
String hexadecimal = toHexString(number2);
hexadecimal = recursiveDecHex(number2);
System.out.printf("Decimal to Hexadecimal (%d) = %s ", number2, hexadecimal);
}
else if (choice == 3 ) {
String binary2 = input.next();
int decimal = toDecimalUsingParseInt(binary2);
decimal = recursiveBin(binary2);
System.out.printf("\n2. Binary to decimal - recursive(%s) = %d ", binary2, decimal);
}
else {
String hex = input.next();
int decimal = toHexUsingParseInt(hex);
decimal = recursiveHexDec(hex);
System.out.printf("Hexadecimal to Decimal (%s) = %d ", hex, decimal);
}
input.close();
}
private static String toBinaryString(int number) {
return Integer.toBinaryString(number);
}
private static String toHexString(int number) {
return Integer.toHexString(number);
}
private static int toDecimalUsingParseInt(String binaryNumber) {
return Integer.parseInt(binaryNumber, 2);
}
private static int toHexUsingParseInt(String number) {
return Integer.parseInt(number, 16);
}
private static String recursive(int number) {
StringBuilder builder = new StringBuilder();
if (number > 0) {
String binaryNumber = recursive(number / 2);
int digit = number % 2;
builder.append(binaryNumber + digit);
}
return builder.toString();
}
private static String recursiveDecHex(int number) {
StringBuilder builder = new StringBuilder();
if (number > 0) {
String hexNumber = recursiveDecHex(number / 16);
String hexCode = "0123456789ABCDEF";
int hexDigit = number % 16;
builder.append(hexNumber + hexCode.charAt(hexDigit));
}
return builder.toString();
}
private static int recursiveBin(String binaryNumber) {
int decimal = 0;
int length = binaryNumber.length();
if (length > 0) {
String substring = binaryNumber.substring(1);
int digit = Character.getNumericValue(binaryNumber.charAt(0));
decimal = digit * (int) Math.pow(2, length - 1) + recursiveBin(substring);
}
return decimal;
}
private static int recursiveHexDec(String hexNumber) {
int decimal = 0;
String hexCode = "0123456789ABCDEF";
hexNumber = hexNumber.toUpperCase();
int length = hexNumber.length();
if (length > 0) {
char ch = hexNumber.charAt(0);
int digit = hexCode.indexOf(ch);
String substring = hexNumber.substring(1);
decimal = digit * (int) Math.pow(16, length - 1) + recursiveHexDec(substring);
}
return decimal;
}
}
When I choose an invalid number (Number that is not in between 1 and 4), the programme will then show "Invalid choice. Please choose a number between 1 and 4", and when I enter a valid number after that, the programme just stops running.
It does not ask me to enter a decimal number if, for example, I choose '1'. What am I missing?
You have no loop, where you try it again and again until a vaild number is entered.
Try this one:
int choice = -1;
while (choice < 0 || choice > 4) {
choice = input.nextInt();
switch (choice) {
case 1:
System.out.println("\nEnter Decimal Number");
break;
case 2:
System.out.println("\nEnter Decimal Number");
break;
case 3:
System.out.println("\nEnter Binary");
break;
case 4:
System.out.println("\nEnter Hexadecimal");
break;
default:
System.out.println("\nInvalid choice. Please choose a number between 1 and 4.");
break;
}
}
But keep in mind, that there is no escape from the loop beside enterin a correct number.
You are waiting for a new entry in the default of the switch. So it just sits there until you put one in.
You could do that part before the switch more easily:
boolean badEntry = true;
do{
System.out.println("Your choice?");
int choice = input.nextInt();
if (( choice<1 )|| (choice>4)) {
System.out.println("\nInvalid choice. Please choose a number between 1 and 4.");
} else {
badEntry = false;
}
}
while (badEntry);
Your program doesn't stop. It's actually waiting for input after you enter the valid number. If you don't believe me, try entering another number after you enter the valid choice. For me, it worked something like this.
Number Conversion Systems
1. Decimal to Binary
2. Decimal to Hexadecimal
3. Binary to Decimal
4. Hexadecimal to Decimal
Your choice?
5
Invalid choice. Please choose a number between 1 and 4.
1
23
Decimal to Binary (23) = 10111
However, by the time you've reached the point in your program where you enter a valid choice, the part that prints out the message such as "Enter decimal number" has already passed; which is why you're not getting that message.

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

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

how can i put my my binary, octal, and Hexadecimal in one loop

So my goal this week was to find the hexadecimal octal and binary for decimal. I was able to get the hexdecimal, binary, and octal but were individual loops on different public class. So i was wondering how could i make this code one and read the hexadecimal, octal, and binary all in one loop.
decimal to hexadecimal
import java.util.Scanner;
public class uncode {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String hex = "";
while (decimal != 0 ) {
int hexValue = decimal % 16;
char hexDigit = (hexValue <= 9 && hexValue > 0) ?
(char) (hexValue + '0') : (char)(hexValue - 10 + 'A');
hex = hexDigit + hex;
decimal = decimal / 16;
}
System.out.println("The hex number is " + hex);
}
}
decimal to octal
import java.util.Scanner;
public class octal {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String octal = "";
while ( decimal > 0 ) {
int remainder = decimal % 8;
octal = remainder + octal;
decimal = decimal / 8;
}
System.out.println("Octal number: " + octal);
}
}
decimal to binary
import java.util.Scanner;
public class GuessNumbers {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String binary = "";
while (decimal > 0) {
int remainder = decimal % 2;
binary = remainder + binary;
decimal = decimal / 2;
}
System.out.println("Binary number: " + binary);
}
}
Easy way would be to use already present converstions, for example
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String hex = Integer.toHexString(decimal);
String oct = Integer.toOctalString(decimal);
String bin = Integer.toBinaryString(decimal);
If you need an integer value, not the string, you can use
int h = Integer.parseInt(hex, 16);
int o = Integer.parseInt(oct, 8);
int b = Integer.parseInt(bin, 2);
Assuming you don't want to use these methods (let's say you have your reasons).
First, you need to put your code in a method, not inside main.
Then you can do something like this:
public class Class {
public static void uncode() {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String hex = "";
while (decimal != 0) {
int hexValue = decimal % 16;
char hexDigit = (hexValue <= 9 && hexValue > 0) ? (char) (hexValue + '0')
: (char) (hexValue - 10 + 'A');
hex = hexDigit + hex;
decimal = decimal / 16;
}
System.out.println("The hex number is " + hex);
}
public static void octal() {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String octal = "";
while (decimal > 0) {
int remainder = decimal % 8;
octal = remainder + octal;
decimal = decimal / 8;
}
System.out.println("Octal number: " + octal);
}
public static void GuessNumbers() {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
String binary = "";
while (decimal > 0) {
int remainder = decimal % 2;
binary = remainder + binary;
decimal = decimal / 2;
}
System.out.println("Binary number: " + binary);
}
public static void allInOne() {
Scanner input = new Scanner(System.in);
System.out.println("Enter a decimal number: ");
int decimal = input.nextInt();
int hex = decimal;
int oct = decimal;
int bin = decimal;
String hexal = "";
String octal = "";
String binary = "";
while (hex > 0 || oct > 0 || bin > 0) {
if (hex > 0) {
// Get Hexal
int hexValue = hex % 16;
char hexDigit = (hexValue <= 9 && hexValue > 0) ? (char) (hexValue + '0')
: (char) (hexValue - 10 + 'A');
hexal = hexDigit + hexal;
hex = hex / 16;
}
if (oct > 0) {
// Get Octal
int remainder = oct % 8;
octal = remainder + octal;
oct = oct / 8;
}
if (bin > 0) {
// Get Binary
int remainder = bin % 2;
binary = remainder + binary;
bin = bin / 2;
}
}
System.out.println("The hex number is " + hexal);
System.out.println("Octal number: " + octal);
System.out.println("Binary number: " + binary);
}
public static void main(String[] args) {
uncode();
octal();
GuessNumbers();
allInOne();
}
}
I tried to make as little changes to your code as possible.
Here i convert from decimal to octal,bineary,hexadecimal by calling method getEveryFromDeci(param1,param2) where param1 - any decimal number and param2- its base value like 8,2,16.
And also i convert octal,bineary,hexadecimal to decimal by calling method allToDeci(param1,param2) where param1 - value of hexadecimal,bineary,octal in string form and param2- base value of hexadecimal
private String getEveryFromDeci(Integer x,Integer y){
List<String> al = deciBin(x,y,new ArrayList<String>());
StringBuffer buffer = new StringBuffer();
for(String s : al)
buffer.append(s);
return buffer.toString();
}
private List<String> deciBin(Integer a,Integer b,List<String> list){
if(a>=b){
deciBin(a/b,b,list);
list.add(a%b > 9 ? getHexaDecimal(a%b):Integer.toString(a%b));
}else
list.add(Integer.toString(a));
return list;
}
private String getHexaDecimal(int d){
String s= null;
switch(d){
case 10:
s="A";
break;
case 11:
s="B";
break;
case 12:
s="C";
break;
case 13:
s="D";
break;
case 14:
s="E";
break;
case 15:
s="F";
break;
}
return s;
}
private int allToDeci(String applyNum,int type){
int sum =0;
char[] ch = applyNum.toCharArray();
for(int pum=0;pum<ch.length;pum++)
sum += Character.isDigit(ch[pum]) ? getAct(ch.length-(pum+1),type) * Character.getNumericValue(ch[pum]) :getAct(ch.length-(pum+1),type) * getNum(ch[pum]);
return sum;
}
private int getNum(char ch){
int num = 0;
switch(ch){
case 'A':
num =10;
break;
case 'B':
num = 11;
break;
case 'C':
num =12;
break;
case 'D':
num =13;
break;
case 'E':
num =14;
break;
case 'F':
num=15;
break;
default:
num =Character.getNumericValue(ch);
break;
}
return num;
}
private int getAct(int k,int p){
int s=1;
if(k >0){
for(int i=0;i<k;i++)
s *=p;
return s;
}else
return 1;
}

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.

Categories