Coverting roman numeral exceptions to decimal - java

For some class homework I need to create a program that converts roman numerals to decimal form. I can convert just fine as long as there are no exception characters such as IV or IX. How do I check for these exceptions? My attempt was to translate both the current character and the next one into decimal, then to compare them and if the next one (going right to left) is smaller to then subtract it. The problem is that I get out of bounds errors from this.
My current code is this:
Scanner keyboard = new Scanner(System.in);
String roman;
int decimal = 0;
int number = 0;
System.out.print("Enter a Roman Numeral to convert to decimal form: ");
roman = keyboard.next();
roman = roman.toUpperCase();
for (int count = roman.length()-1; count >= 0; count--)
{
char numeral = roman.charAt(count);
switch (numeral){
case 'I':
decimal = 1;
break;
case 'V':
decimal = 5;
break;
case 'X':
decimal = 10;
break;
case 'L':
decimal = 50;
break;
case 'C':
decimal = 100;
break;
case 'D':
decimal = 500;
break;
case 'M':
decimal = 1000;
break;
default:
System.out.println("Error: Invalid character detected.");
break;
}
number = number + decimal;
}
System.out.println("The decimal equivalent is: " + number);
System.out.println("Later!");
I'm still a beginner and most of the information I see on this kind of problem uses advanced solutions that I simply don't understand. I know I need to compare the characters but I'm not sure how to do this in a way that won't eventually go out of bounds.
EDIT: Solved! After posting the question I was struck by insight and solved the problem myself. This code works but I would appreciate any insights into how to improve it!
Scanner keyboard = new Scanner(System.in);
String roman;
int decimal = 0;
int number = 0;
int last = 0;
System.out.println("This program converts Roman Numerals to decimal form.");
System.out.println("Note: Roman Numerals are I, V, X, L, C, D and M.");
System.out.println("All letters entered will be treated as capitalized.");
System.out.print("Enter a Roman Numeral to convert to decimal form: ");
roman = keyboard.next();
roman = roman.toUpperCase();
for (int count = roman.length()-1; count >= 0; count--)
{
char numeral = roman.charAt(count);
switch (numeral){
case 'I':
decimal = 1;
break;
case 'V':
decimal = 5;
break;
case 'X':
decimal = 10;
break;
case 'L':
decimal = 50;
break;
case 'C':
decimal = 100;
break;
case 'D':
decimal = 500;
break;
case 'M':
decimal = 1000;
break;
default:
System.out.println("Error: Invalid character detected.");
System.exit(0);
break;
}
if (decimal >= last){
number = number + decimal;
}
else {
number = number - decimal;
}
last = decimal;
}
System.out.println("The decimal equivalent is: " + number);
System.out.println("Later!");

Well, a decimal is ##.##, and an integer is ##, so you should probably change demical to num.
Set the number as you already do, and add a check after it for the exception character. But first ensure that it exists:
if(this character is not the first && the previous character is an exception)
adjust the number as necessary
This will avoid an out-of-bounds exceptions.

Related

Random Math Question Generator not following while loop

I'm a new java coder getting into it doing a project. I coded it how i believe the system would execute it and yet it doesn't seem to be following the While loops requirements. I want it to generate random number, do a random operation, then ask the user for an answer. The answer must be not decimal and the random numbers must be below 10 to make the questions easier as its for a lower target audience. I'm kind of stuck now on this piece. Apologies if this doesn't make sense as i say it is a first attempt for me.
import java.util.Random;
import java.lang.Math;
import java.util.Scanner;
public class RandomisedQuestions{
public static void QuestionGenerator(){
Random r = new Random();
Scanner s = new Scanner(System.in);
int intA = 0;
int intB = 0;
char operator ='?';
double value = 1.2;
for (int i = 0; i < 3; i++) {
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
if (intA <= 0 && intB <= 0){
intA = (int)(10.0 * Math.random());//the (int) forces the number to be an int
intB = (int)(10.0 * Math.random());
System.out.println(intA + intB);
}
while ((value % 1) !=0 && value > 1){//Runs while value is not whole
switch (r.nextInt(4)){
case 0: operator = '+';
value = intA+intB;
break;
case 1: operator = '-';
value = intA-intB;;
break;
case 2: operator = '*';
value = intA*intB;;
break;
case 3: operator = '/';
value = intA/intB;;
break;
default: operator = '?';
}
//System.out.println(operator);
}
System.out.println(intA +""+ operator +""+ intB);
System.out.println("Enter the answer");
int uGuess = s.nextInt();
if (uGuess == value){
System.out.println("Correct");
}
else{
System.out.println("Incorrect");
}
}
}
}
It's better to use ThreadLocalRandom.nextInt to generate your numbers:
// At the start of your program initialize the generator:
ThreadLocalRandom r = ThreadLocalRandom.current();
// Later use it:
do {
intA = ThreadLocalRandom.nextInt(1, 10);
intB = ThreadLocalRandom.nextInt(1, 10);
switch (r.nextInt(4)) {
case 0: operator = '+';
value = intA + intB;
break;
case 1: operator = '-';
value = intA - intB;
break;
case 2: operator = '*';
value = intA * intB;
break;
case 3: operator = '/';
value = (double)intA / intB;
break;
default: operator = '?';
}
} while (value != (int)value || value <= 1);
Also note the conversion to double in division case, otherwise the division will be performed for integer types.

Java, Calculating When Operator Is A Variable

Lets say you have:
int number1 = 5;
int number2 = 5;
char operator = '*';
How can I use the character for a calculation: number1 (operator) number2 = 5*5
Edit: It was my first time posting anything on this site and I am also an amateur, so I guess thats why I got downvoted 8x cus it was unclear but ty for the people who answered. Will be more thorough next time :)
You can use switch or a simple if condition for an example
if(operator == '*'){
int total = number1 * number2;
}else if(operator == '+'){
int total = number + number2;
}
Like this you can do the calculations
you can use switch case for your purpose.
if operator is char type than
int result=0;
switch(operator){
case '+':
result=number1+number2;
case '-':
result=number1-number2;
case '*':
result=number1*number2;
case '/':
result=number1/number2;
}

Count the number of occurrences of all the digits in the string

My task is write a program to take string as input(only numbers) and for each digit starting from 0 to 9, print the count of their occurrences in the string.
I have completed it. I have declared 10 integers with zero. Each integer will count the corresponding integers. But in the last when I am printing the result it is giving me the result as 48+count
Count represents the number of count of values occurrences.
For the correct result I need to subtract 48. I am unable to understand why I am getting value.
class TestClass {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
int a='0',b='0',c='0',d='0',e='0',f='0',g='0',h='0',i='0',j='0';
String s=sc.next();
OUTER:
for (int k = 0; k<s.length(); k++) {
char ch=s.charAt(k);
switch (ch) {
case '0':
a++;
break;
case '1':
b++;
break;
case '2':
c++;
break;
case '3':
d++;
break;
case '4':
e++;
break;
case '5':
f++;
break;
case '6':
g++;
break;
case '7':
h++;
break;
case '8':
i++;
break;
case '9':
j++;
break;
case ' ':
break OUTER;
default:
break;
}
}
System.out.println("0 "+(a-48));
System.out.println("1 "+(b-48));
System.out.println("2 "+(c-48));
System.out.println("3 "+(d-48));
System.out.println("4 "+(e-48));
System.out.println("5 "+(f-48));
System.out.println("6 "+(g-48));
System.out.println("7 "+(h-48));
System.out.println("8 "+(i-48));
System.out.println("9 "+(j-48));
}
}
please anyone explain me what I can do for removing this extra value in this program.
thanks
Instead of
int a = '0'
use
int a = 0
'0' is equal to 48 in ASCII and it is a character, not a number. So by int a = '0', you actually initialize a to 48
I would suggest to use an array instead. it'll be easier to process.
String str = sc.next();
char[] input = str.toCharArray();
int[] count = new int[10]; // stores the count, int array initialized to 0 by default
for(int i = 0 ; i < input.length; i++){
// get index value by substracting ASCII value
int c = input[i] - 48; // 48 being ASCII Value of '0'
count[c]++;
}
// print the count array
System.out.println(Arrays.toString(count));
count[0] has no of 0's
count[1] has no of 1's
.....

Only positive sums - Random sum generator [JAVA]

I'm trying to create a random sum generator that generators random sums!
The only problem with what I created is, it can generate sums that have a negative result as well. So I want it to only generate sums with positive outcomes.
Example:
7-10 = -3
My code:
number1 = (int)(Math.random()* LT) + 1;
number2 = (int)(Math.random()* LT) + 1;
operator = (int)(Math.random()* OP) + 1;
switch(operator) {
case 1:
operation = "+";
result = number1 + number2;
break;
case 2:
operation = "-";
result = number1 - number2;
break;
case 3:
operation = "*";
result = number1 * number2;
break;
case 4:
operation = "/";
result = number1 * number2;
break;
}
Since you will always be dealing with positive integers your only issue is checking for negative numbers in your subtraction case. I would also recommend switching to the Random class to generate random integers. One way to get around negative results is to flip the numbers you are subtracting.
boolean flip = false;
int num1, num2, op, result;
String operation;
Random r = new Random();
num1 = r.nextInt(8)+2;
num2 = r.nextInt(8)+2;
op = r.nextInt(4);
switch(op) {
case 0:
// Always be positive.
operation = "+";
result = num1+num2
break;
case 1:
// Could be negative if num2 is larger than num1. Simply flip the numbers.
flip = num1 < num2;
operation = "-";
result = flip ? num2-num1 : num1-num2;
break;
case 2:
// Always be positive.
operation = "*";
result = num1*num2;
break;
case 3:
// Always be positive.
operation = "/";
result = num1/num2;
break;
}
The simplest fix you can do is let the random operation complete. I assume you do multiple loops of {add,sub,mult,divide}. If the final result is negative, convert it back to positive.
But a more distributed random number generation can be done with the java runtime:
double d = java.lang.Math.random() * MAX_RANDOM_VALUE; // MAX_RANDOM_VALUE is a max value you define, like 100000
int result = (int)d;
You haven't mentioned anything about required distribution of outputs, but if it's really as simple as making sure you have no negative outputs, you could pass each output through Math.abs() before returning it...
As far as I understood you want to pick random number from the set of positive integers which can be written as a + b where a and b are integers. Since every positive integer between 1 and the maximum value of a+b, can be written like this, you just want to select a random positive integer.
int result = new Random().nextInt(maxPossibleSumValue);
Since random number generated would be in the range 0-1. You will get negative result only when you are subtracting two numbers and number2 is greater than number1. In this case you can simply swap number1 and number2 if number2 is greater than number1.

Compare two hex strings to find number of matching bits

I have two hex strings:
string x = "928fe46f228555621c7f42f3664530f9";
string y = "56cd8c4852cf24b1182300df2448743a";
I'm trying to convert them to binary to find how many bits matches between the two hex strings.
I used this function to convert HEX to Binary:
string GetBinaryStringFromHexString (string sHex)
{
string sReturn = "";
for (int i = 0; i < sHex.length (); ++i)
{
switch (sHex [i])
{
case '0': sReturn.append ("0000"); break;
case '1': sReturn.append ("0001"); break;
case '2': sReturn.append ("0010"); break;
case '3': sReturn.append ("0011"); break;
case '4': sReturn.append ("0100"); break;
case '5': sReturn.append ("0101"); break;
case '6': sReturn.append ("0110"); break;
case '7': sReturn.append ("0111"); break;
case '8': sReturn.append ("1000"); break;
case '9': sReturn.append ("1001"); break;
case 'a': sReturn.append ("1010"); break;
case 'b': sReturn.append ("1011"); break;
case 'c': sReturn.append ("1100"); break;
case 'd': sReturn.append ("1101"); break;
case 'e': sReturn.append ("1110"); break;
case 'f': sReturn.append ("1111"); break;
}
}
return sReturn;
}
So String x in binary is-->
10010010100011111110010001101111001000101000010101010101011000100001110001111111010000101111001101100110010001010011000011111001
and String y in binary is --> 01010110110011011000110001001000010100101100111100100100101100010001100000100011000000001101111100100100010010000111010000111010
But now I'm stuck, how can I xor the two strings to find the number of matching bits ? and how can I count them?
It doesn't matter whether I use Java or C++, can anyone help please
Thank you,
In Java it's pretty easy.
public static int numberOfMatchingOnes(String a, String b) {
BigInteger aNumber = new BigInteger(a, 16);
BigInteger bNumber = new BigInteger(b, 16);
return aNumber.xor(bNumber).bitCount();
}
In C++ you might use a bitset. What you're looking for is called Hamming weight.
If you really want to do it without BigInteger:
Take 4 chars of both strings, convert them into an int, xor them and count the one-bits. Repeat until the strings end.
public static int numberOfMatchingOnes(String a, String b) {
if (a.length() != b.length() || a.length() % 4 != 0) {
throw new IllegalArgumentException("invalid strings");
}
int totalCount = 0;
for (int i = (a.length()-1)/4; i >= 0; i--) {
int aValue = Integer.valueOf(a.substring(i * 4, i * 4 + 4), 16);
int bValue = Integer.valueOf(b.substring(i * 4, i * 4 + 4), 16);
totalCount += Integer.bitCount(aValue ^ bValue);
}
return totalCount;
}
You can look at the Java Sourcecode to see how bitCount() works.
You have two strings. Why not run through them character by character and see if they match or not? Initialize a counter to zero and start incrementing them for each match and display at the end of the loop. Much simpler.
Here is a one-liner solution though (with the power of all the libraries in the world):
System.out.println(StringUtils.countMatches(new BigInteger("928fe46f228555621c7f42f3664530f9",16).xor(new BigInteger("56cd8c4852cf24b1182300df2448743a",16)).toString(2),"1"));
It depends your purpose if you want to find where they matched together you can use AND
in C :
#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 & b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
}
the above code from right to left compare numbers in binary and wherever a two bit were 1 then return 1 else return 0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if you want to find where are the same or not use XOR
in C :
#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 ^ b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
}

Categories

Resources