Java booth algorithm Shift or addition trouble - java

I just need a little help programming booths algorithm into java, I'm really not sure how to fix somethings, right now adding the right shift makes the entire answer 1(will show a few examples of inputs and outputs to explain and show) I know its converting to binary properly so I think my problem is in my shift and adding function.
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
System.out.print("Enter the first number: ");
int operand1 = sc.nextInt();
System.out.print("Enter the second number: ");
int operand2 = sc.nextInt();
String answer = multiply(operand1, operand2);
System.out.println(answer);
}
static String appendZeros(int n){
String result = "";
for(int i = 0; i < n; i++) result += "0";
return result;
}
public static String toBinary(int x, int len)
{
if (len > 0)
{
return String.format("%" + len + "s",
Integer.toBinaryString(x)).replaceAll(" ", "0");
}
return null;
}
static String add(String a, String b){
String result = "";
char carry = '0';
for(int i = a.length()-1; i >= 0; i--){
String condition = "" + a.charAt(i) + b.charAt(i) + carry;
switch(condition){
case "000": result = "0" + result; break;
case "001": result = "1" + result; carry = '0'; break;
case "010": result = "1" + result; break;
case "011": result = "0" + result; break;
case "100": result = "1" + result; break;
case "101": result = "0" + result; break;
case "110": result = "0" + result; carry = '1'; break;
case "111": result = "1" + result; break;
}
}
return result;
}
static String rightShift(String str){
String result = "";
for(int i = 0; i < str.length(); i++){
if(i == 0) result += str.charAt(i);
else result += str.charAt(i-1);
}
return result;
}
static String multiply(int a, int b){
String op1 = toBinary(a, 8);
String op2 = toBinary(b, 8);
String negop2 = toBinary(-b, 8);
if (op1.length() > 8)
{
op1 = op1.substring(op1.length() - 8);
}
if (op2.length() > 8)
{
op2 = op2.substring(op2.length() - 8);
}
if (negop2.length() > 8)
{
negop2 = negop2.substring(negop2.length() - 8);
}
System.out.println(op1 + " " + op2 + " " + negop2);
char prev = '0';
String product = appendZeros(16-op1.length())+op1;
for(int i = 0; i < 8; i++){
if(i > 0) prev = product.charAt(15);
if(product.charAt(15)=='0' && prev == '1'){
String temp = appendZeros(8-op2.length()) + op2 + appendZeros(8);
product = add(product, temp);
}
if(product.charAt(15)=='1' && prev == '0'){
String temp = appendZeros(8-negop2.length()) + negop2 + appendZeros(8);
product = add(product, temp);
}
product=rightShift(product);
}
return product;
}
input 9 1 output 1111111111111111 expected 0000000000001001 input 9 9
output 1111111111110111 expected 0000000001010001

I figured out my problem, the prev variable was being called too late so it didn't update the function properly, the prev value needed to be updated before the shift occurred. I moved it to right before the shift function was called and removed the if statement and it fixed it, it works perfectly now.
for(int i = 0; i < 8; i++){
//System.out.println("Did it change back?" + product.charAt(15) + prev);
//System.out.println("i = " + i);
if(product.charAt(15)=='0' && prev == '1'){
String temp = appendZeros(8-op2.length()) + op2 + appendZeros(8);
System.out.println(temp);
product = add(product, temp);
System.out.println("Add " + product);
}
if(product.charAt(15)=='1' && prev == '0'){
String temp = appendZeros(8-negop2.length()) + negop2 + appendZeros(8);
System.out.println(temp);
product = add(product, temp);
System.out.println("Subtract " + product);
}
prev = product.charAt(15);
product=rightShift(product);
System.out.println("Shift " + product);

Related

Is there a reason why I cannot return inside of a While loop?

I am working on a method in my program which has to return the value purchaseMethod. The while loop needs to run until "Q" is input into the console. The issue I am having is that I cannot return while in a while loop. Is there any way around this? Possibly making an array or for loop? If the return statement is necessary to be outside of the while-loop, how would I keep the values to total for the purchaseAmount.
public static int getShoppingList(){
Scanner input = new Scanner(System.in);
int eight = 8;
int hat = 32;
int patch = 2;
int sword = 20;
int map = 100;
int shirt = 150;
int quanEight = 0;
int quanHat = 0;
int quanPatch = 0;
int quanSword = 0;
int quanMap = 0;
int quanShirt = 0;
int count = 0;
System.out.println("Enter Item Code, ? or Q: ");
String code = input.next();
// Convert input into character
char ch = code.charAt(0);
// Convert string into uppercase
ch = Character.toUpperCase(ch);
// Calculate total
while (count != 0){
int purchaseAmount = ( quanEight * eight) + ( quanHat * hat) + ( quanPatch * patch) + ( quanSword * sword) + ( quanShirt * shirt) + ( quanMap * map);
if (ch == '?'){
System.out.println("Valid Item codes are: 8 I H M S T.");
System.out.println("Q to quit.");
}
else if (ch == '8'){
quanEight ++;
}
else if (ch == 'I'){
quanHat++;
}
else if (ch == 'H'){
quanPatch++;
}
else if (ch == 'M'){
quanMap++;
}
else if (ch == 'S'){
quanSword++;
}
else if (ch == 'T'){
quanShirt++;
}
else if (ch == 'Q'){
count++;
System.out.println("Pirate Trading Post");
System.out.println(quanEight + " Genuine Piece Of Eight\n " + quanHat + " Pirate Hat\n " + quanPatch +
" Eye Patch\n " + quanSword + " Sword\n " + quanMap + " Treasure Map\n " + quanShirt + " T-Shirt\n ");
System.out.println("Total: " + purchaseAmount + " bits");
return purchaseAmount;
}
}
}
The problem is a compile problem with this:
int count = 0;
while (count != 0){ // count **IS** 0, does not enter
// your stuff
}
// no return
If with the return command you intend to return the purchaseAmount to the caller of getShoppingList() method, I suggest you moving the return to the end of the method and putting a break in its while instead of purchaseAmount. Like this:
while (count != 0){
// your stuff
if (...) {
// ...
} else if (ch == 'Q'){
// ...
break;
}
}
return purchaseAmount;

How to check if a number is a palindrome?

I wrote a piece of code for a class homework. However I thought it was quite long! Is there a more optimized way to do this?
String text = input.readLine();
int num = (text.length())/2;
double letter = (double)(text.length())/2;
String s1 = text.substring(0,num);
int u1 = Integer.parseInt(s1);
if (letter%1==0) {
StringBuffer s2 = new StringBuffer(text.substring(num));
s2 = s2.reverse();
String t2 = s2.toString();
int u2 = Integer.parseInt(t2);
if (u1==u2) {
System.out.println("Palindrome");
} else {
System.out.println("FAIL");
}
} else {
StringBuffer s2 = new StringBuffer(text.substring(num+1));
s2= s2.reverse();
String t2 = s2.toString();
int u2 = Integer.parseInt(t2);
if (u1==u2) {
System.out.println("Palindrom");
}else {
System.out.println("FAIL");
}
}
You don't need to convert the string back to number in order to compare them. You can use string's equals() method to check if they are equal. Check this out (with necessary changes this will work for any string though, not just numbers).
int num = 12300321;
String numString = String.valueOf(num);
String reverseNumString = new StringBuilder(numString).reverse().toString();
if(numString.equals(reverseNumString)) {
System.out.println(num + " is a Palindrome!");
}
else {
System.out.println(num + " is not a Palindrome!");
}
Output:
12300321 is a Palindrome!
Alternate method (using only number manipulation; will work for integers only)
int num = 12300321;
int numCopy = num;
int reverseNumInt = 0;
while(numCopy != 0) {
reverseNumInt = reverseNumInt * 10 + numCopy % 10;
numCopy /= 10;
}
if(reverseNumInt == num) {
System.out.println(num + " is a Palindrome!");
}
else {
System.out.println(num + " is not a Palindrome!");
}
Your code works, but handling the numbers digit by digit is simpler and more readable:
public static boolean isPalindromic(String num) {
for(int i = 0, len = num.length() ; i < len/2 ; i++) {
if(num.charAt(i) != num.charAt(num.charAt(len-i-1))) return false;
}
return true;
}

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("_____________");
}

Searching an object array for certain values

Hey everyone so I am stuck on the last part of this program that I have been doing for an assignment. So generally I am given a large list of names and numbers that represent popularity ranks for names in certain decades. This is what the file looks like <----- this is a link to see the names.txt
So I created a method that sorts the list in a certain decade which is the getIndexOfSmallest and interchange. Every decade has two names that are ranked the same so between the years of 1900-1909 there are two names that are ranked 1, two names that are ranked 2, two names that are ranked 3 and so on. The last part of the program and the one I need help with is suppose to sort through the object array and find any decades where there is only one name for one rank or no names for a certain rank. The output will be sent to a file and it will look like this. <------ this is another link to see the expected output
This is what my code looks like. This is my Name code that creates the objects:
public class Name{
private String givenName;
private int[] ranks = new int[12];
public Name(String name, int[] popularityRanks){
givenName = name;
for (int i = 0; i < 11; i++){
ranks[i] = popularityRanks[i];
}
}
public String getName(){
return givenName;
}
public int getPop(int decade){
if (decade >= 0 && decade <= 10){
return ranks[decade];
}
else{
return -1;
}
}
public String getHistoLine(int decade){
String histoLine = ranks[decade] + ": ";
double popularity = (1000 - ranks[decade]) / 11.7;
int histo = (int)popularity;
if(popularity != 0){
for (int i = 0; i < histo; i++){
histoLine += "*";
}
}
return histoLine;
}
public String getHistogram(){
String histogram = "";
for (int i = 0; i < 11; i++){
histogram += this.getHistoLine(i) + "\n";
}
return histogram;
}
}
This is my NameApp which is where my main is at:
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class NameApp{
private static boolean validInput;
private static boolean stillWorking = true;
private static boolean validDecade;
private static boolean validName;
static Scanner keyboard = new Scanner(System.in);
// Main method
public static void main(String[] args) throws FileNotFoundException{
String[] nameArray = readNamesFile();
Name[] list = new Name[nameArray.length];
loadNames(list, nameArray);
char choice;
do {
do {
displayMenu();
choice = getUserInput();
} while (!validInput);
switch (choice){
case 'A':
displayHistogram(list);
break;
case 'B':
compareTwoNames(list);
break;
case 'C':
displayTopTenNames(list);
break;
case 'D':
writeAnomaliesToFile(list);
stillWorking = false;
break;
default:
break;
}
} while (stillWorking);
}
/*
* This method will read the file name names.txt and load the names and populations into a string array.
*/
private static String[] readNamesFile() throws FileNotFoundException{
String[] nameArray = new String[4429];
Scanner inputStream = null;
String fileName = "names.txt";
inputStream = new Scanner (new File(fileName));
int i = 0;
while (inputStream.hasNextLine()){
nameArray[i] = inputStream.nextLine();
i++;
}
inputStream.close();
return nameArray;
}
/*
* load names method will take a Name array and the string array from the readNamesFile method. This method will split the names and the population ranks and send them to the constructor in Name.java.
*/
private static void loadNames(Name[] list, String[] nameArray){
int length;
int spacePos;
int[] popRanks = new int[11];
String name;
String linePop;
for (int i = 0; i < nameArray.length; i++){
length = nameArray[i].length();
spacePos = nameArray[i].indexOf(" ");
name = nameArray[i].substring(0,spacePos);
linePop = nameArray[i].substring(spacePos + 1, length);
for (int j = 0; j < 11; j++){
popRanks[j] = Integer.parseInt(linePop.split(" ")[j]);
}
list[i] = new Name(name, popRanks);
}
}
/*
* displayMenu method will display the menu that the user will select their program function.
*/
private static void displayMenu(){
System.out.println("Enter the character corresponding to your selection:");
System.out.println("\ta - Print histogram for a name");
System.out.println("\tb - Compare two names in a decade");
System.out.println("\tc - Print top ten names for a decade");
System.out.println("\td - Quit (display file anomalies)");
}
/*
* getUserInput is a method that will accept a string input from the user it will send this string to two different helper methods.
*/
private static char getUserInput(){
String selection = keyboard.nextLine();
System.out.println(" Your selection: " + selection);
checkUserInput(selection);
char choice = stringToChar(selection);
return choice;
}
/*
* helper method: checkUserInput will accept the user input from getUserInput and test the input to see if the input is a valid input from the user. If it is not set the instance boolean variable to false if it is set it to true.
*/
private static boolean checkUserInput(String selection){
if (!selection.equalsIgnoreCase("a") && !selection.equalsIgnoreCase("b") && !selection.equalsIgnoreCase("c") && !selection.equalsIgnoreCase("d")){
System.out.println("Invalid input. Try again...");
return validInput = false;
}
else {
return validInput = true;
}
}
/*
* helper method: stringToChar method will take the input that the user entered after it has been tested to see if it is valid and this method will change the input to a character value. This will also make the character to an upper case letter.
*/
private static char stringToChar(String selection){
char choice = selection.charAt(0);
choice = Character.toUpperCase(choice);
return choice;
}
/*
* Menu option: A. This method will take a user input for the name they want and display the histogram for the selected name.
*/
private static void displayHistogram(Name[] list){
String nameInput;
String histogram;
int nameLocation;
do {
nameInput = nameEntry();
nameLocation = checkListArray(nameInput, list);
if (!validName){
System.out.println("The name, " + nameInput + ", was not found!");
}
} while (!validName);
histogram = list[nameLocation].getHistogram();
System.out.println("Histogram for name, " + list[nameLocation].getName() + ":");
System.out.println(histogram);
}
private static void compareTwoNames(Name[] list){
String nameOne;
String nameTwo;
String oneHistoLine;
String twoHistoLine;
int oneLocation;
int twoLocation;
int decade;
do {
nameOne = nameEntry();
oneLocation = checkListArray(nameOne, list);
if (!validName){
System.out.println("The first name, " + nameOne + ", was not found!");
}
} while (!validName);
do {
nameTwo = nameEntry();
twoLocation = checkListArray(nameTwo, list);
if (!validName){
System.out.println("The second name, " + nameTwo + ", was not found!");
}
} while(!validName);
decadeMenu();
decade = decadeSelection();
oneHistoLine = list[oneLocation].getHistoLine(decade);
twoHistoLine = list[twoLocation].getHistoLine(decade);
System.out.println("Data for " + list[oneLocation].getName());
System.out.println(" " + oneHistoLine);
System.out.println("Data for " + list[twoLocation].getName());
System.out.println(" " + twoHistoLine);
}
private static void displayTopTenNames(Name[] list){
int decade;
int count = 0;
int l = 0;
String[] decadeName = new String[20];
Name[] temp = new Name[list.length];
decadeMenu();
decade = decadeSelection();
for (int i = 0; i < list.length; i++){
temp[i] = list[i];
}
for (int index = 0; index < temp.length; index++){
int smallestIndex = getIndexOfSmallest(decade, index, temp);
interchange(decade, index, smallestIndex, temp);
}
do {
if (temp[l].getPop(decade) == 0){
l++;
}
else {
decadeName[count] = temp[l].getName() + " " + "(" + temp[l].getPop(decade) + ")";
count++;
l++;
}
} while (count < 20);
writeTopTen(decadeName, decade);
}
private static void writeAnomaliesToFile(Name[] list){
System.out.println("Terminating... but first the anomalies in the data file:");
checkAnomalies(list);
System.out.println("Anomalies written to anomalies.txt.");
}
private static String nameEntry(){
String nameInput = "";
System.out.println("Enter a name: ");
nameInput = keyboard.nextLine();
return nameInput;
}
private static int checkListArray(String nameInput, Name[] list){
int nameLocation = -1;
int listLength = list.length;
for (int i = 0; i < listLength; i++){
if (nameInput.equalsIgnoreCase(list[i].getName())){
validName = true;
return nameLocation = i;
}
}
if (nameLocation == -1){
validName = false;
return nameLocation;
}
return nameLocation;
}
private static void decadeMenu(){
System.out.println("Enter number correpsonding to your decade:");
System.out.println(" 1 - 1900-1909");
System.out.println(" 2 - 1910-1919");
System.out.println(" 3 - 1920-1929");
System.out.println(" 4 - 1930-1939");
System.out.println(" 5 - 1940-1949");
System.out.println(" 6 - 1950-1959");
System.out.println(" 7 - 1960-1969");
System.out.println(" 8 - 1970-1979");
System.out.println(" 9 - 1980-1989");
System.out.println(" 10 - 1990-1999");
System.out.println(" 11 - 2000-2005");
}
private static int decadeSelection(){
String decadeChoice;
int decade;
do {
System.out.println("Enter a decade: ");
decadeChoice = keyboard.nextLine();
decade = checkDecade(decadeChoice);
} while (!validDecade);
return decade;
}
private static int checkDecade(String decadeChoice){
int decade = 0;
try {
decade = Integer.parseInt(decadeChoice);
}
catch (Exception e){
System.out.println("That is not an integer. Please try again.");
validDecade = false;
return decade;
}
if (decade < 1 || decade > 11){
System.out.println("Enter an integer between 1 and 11");
validDecade = false;
return decade;
}
else {
validDecade = true;
decade = changeDecade(decade);
return decade;
}
}
private static int changeDecade(int decade){
int newDecade = 0;
switch (decade){
case 1:
newDecade = 0;
break;
case 2:
newDecade = 1;
break;
case 3:
newDecade = 2;
break;
case 4:
newDecade = 3;
break;
case 5:
newDecade = 4;
break;
case 6:
newDecade = 5;
break;
case 7:
newDecade = 6;
break;
case 8:
newDecade = 7;
break;
case 9:
newDecade = 8;
break;
case 10:
newDecade = 9;
break;
case 11:
newDecade = 10;
break;
default:
break;
}
return newDecade;
}
private static int getIndexOfSmallest(int decade, int startIndex, Name[] temp){
int min = temp[startIndex].getPop(decade);
int indexOfMin = startIndex;
for (int index = startIndex + 1; index < temp.length; index++){
if (temp[index].getPop(decade) < min){
min = temp[index].getPop(decade);
indexOfMin = index;
}
}
return indexOfMin;
}
private static void interchange(int decade, int i, int j, Name[] temp){
Name tempInt = temp[i];
temp[i] = temp[j];
temp[j] = tempInt;
}
private static String decadeYears(int decade){
String decadeYear = "";
switch (decade){
case 0:
decadeYear = "1900 - 1909";
break;
case 1:
decadeYear = "1910 - 1919";
break;
case 2:
decadeYear = "1920 - 1929";
break;
case 3:
decadeYear = "1930 - 1939";
break;
case 4:
decadeYear = "1940 - 1949";
break;
case 5:
decadeYear = "1950 - 1959";
break;
case 6:
decadeYear = "1960 - 1969";
break;
case 7:
decadeYear = "1970 - 1979";
break;
case 8:
decadeYear = "1980 - 1989";
break;
case 9:
decadeYear = "1990 - 1999";
break;
case 10:
decadeYear = "2000 - 2005";
break;
default:
break;
}
return decadeYear;
}
private static void writeTopTen(String[] decadeName, int decade){
String years;
years = decadeYears(decade);
System.out.println("Ten most popular names (male and female) during the decade " + years + " were:");
for (int i = 0; i < 20; i += 2){
System.out.printf("%20s\t%20s\n", decadeName[i],decadeName[i + 1]);
}
}
private static void checkAnomalies(Name[] list){
Name[] temp = new Name[list.length];
int anomalyCount = 0;
int popTwo = 0;
int popOne = 0;
String[] anomalies = new String[list.length];
for (int i = 0; i < list.length; i++){
temp[i] = list[i];
}
for (int decade = 0; decade < 11; decade++){
for (int index = 0; index < temp.length; index++){
int smallestIndex = getIndexOfSmallest(decade, index, temp);
interchange(decade, index, smallestIndex, temp);
}
int rank = 0;
for (int i = 1; i < temp.length - 1; i += 2){
popOne = temp[i].getPop(decade);
popTwo = temp[i+1].getPop(decade);
if (popOne != 0){
rank++;
}
if (popOne == rank && popTwo != rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "One name (" + temp[i].getName() + ") for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
anomalyCount++;
}
else if (popOne != rank && popTwo == rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "One name (" + temp[i+1].getName() + ") for " + decadeYear + ", rank " + temp[i+1].getPop(decade) + ".";
anomalyCount++;
}
else if (popOne != rank && popTwo != rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "No names for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
anomalyCount++;
}
}
}
}
}
This is the information provided by my professor:
There are 1,065 anomalies: in some cases, only one name with a particular rank in a decade or in other cases, no names in a decade with a particular rank. With 11 decades and 999 ranks to check, 1065 is only about 9.7% of the name-pairs that are broken or anomalous. There should be a pair of names for each rank (999) in each decade (11): this gives 10,989 name-pairs. Your code to do this will need to check each name in each decade for each rank in order to find all 1065 anomalies.
When I was debugging my program I saw that the ranks end on odd numbers. which is why I started my loop in checkAnomalies at 1 instead of 0 (considering that at 0 the names rank will be 0 and that is considered to be a name that was picked 1000 or less). When I run the program with:
String[] anomalies = new String[1065];
I get this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1065
at NameApp.checkAnomalies(NameApp.java:512)
at NameApp.writeAnomaliesToFile(NameApp.java:259)
at NameApp.main(NameApp.java:43)
and when I change my code to be:
String[] anomalies = new String[temp.length];
I get this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4429
at NameApp.checkAnomalies(NameApp.java:502)
at NameApp.writeAnomaliesToFile(NameApp.java:259)
at NameApp.main(NameApp.java:43)
I figure my error is in my loops but I can't figure out where.. I figured my loops are finding way more errors then their really is.. Just wondering if anyone can help me out with this.. It is really the only part that I need left. Thanks in advance
EDIT:
This is the relevant code for what I need help with:
private static void writeAnomaliesToFile(Name[] list){
System.out.println("Terminating... but first the anomalies in the data file:");
checkAnomalies(list);
System.out.println("Anomalies written to anomalies.txt.");
}
method that is called:
private static void checkAnomalies(Name[] list){
Name[] temp = new Name[list.length];
int anomalyCount = 0;
int popTwo = 0;
int popOne = 0;
String[] anomalies = new String[list.length];
for (int i = 0; i < list.length; i++){
temp[i] = list[i];
}
for (int decade = 0; decade < 11; decade++){
for (int index = 0; index < temp.length; index++){
int smallestIndex = getIndexOfSmallest(decade, index, temp);
interchange(decade, index, smallestIndex, temp);
}
int rank = 0;
for (int i = 1; i < temp.length - 1; i += 2){
popOne = temp[i].getPop(decade);
popTwo = temp[i+1].getPop(decade);
if (popOne != 0){
rank++;
}
if (popOne == rank && popTwo != rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "One name (" + temp[i].getName() + ") for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
anomalyCount++;
}
else if (popOne != rank && popTwo == rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "One name (" + temp[i+1].getName() + ") for " + decadeYear + ", rank " + temp[i+1].getPop(decade) + ".";
anomalyCount++;
}
else if (popOne != rank && popTwo != rank){
String decadeYear = decadeYears(decade);
anomalies[anomalyCount] = "No names for " + decadeYear + ", rank " + temp[i].getPop(decade) + ".";
anomalyCount++;
}
}
}
}
Solved myself just had to sleep on it:
private static void checkAnomalies(Name[] list)
throws FileNotFoundException{
Name[] temp = new Name[list.length];
String[] anomalies = new String[1065];
int anomalyCount = 0;
for (int i = 0; i < list.length; i++){
temp[i] = list[i];
}
for (int decade = 0; decade < 11; decade++){
for (int ranks = 1; ranks < 1000; ranks++){
int found = 0;
String tempName = "";
String decadeYear = decadeYears(decade);
for (int i = 0; i < temp.length; i++){
if (temp[i].getPop(decade) == ranks){
found++;
}
if (found == 1 &&
temp[i].getPop(decade) == ranks){
tempName = temp[i].getName();
}
}
if (found == 0){
anomalies[anomalyCount] = "No names "
+ "for " + decadeYear + ", rank "
+ ranks + ".";
anomalyCount++;
}
else if (found == 1){
anomalies[anomalyCount] = "One "
+ "Name (" + tempName + ") for "
+ decadeYear + ", rank "
+ ranks + ".";
anomalyCount++;
}
}
}
writeAnomaliesFile(anomalies);
}
/*
* Helper method: this method will create and write
* each anomalies to a text document called
* anomalies.txt.
*/
private static void
writeAnomaliesFile(String[] anomalies)
throws FileNotFoundException{
String fileName = "anomolies.txt";
PrintWriter outputStream = null;
outputStream = new PrintWriter(fileName);
for (int i = 0; i < anomalies.length; i++){
outputStream.println(anomalies[i]);
}
outputStream.close();
}

not evaluation doubles

Okay so I am sending doubles value to this and its not parsing them as doubles instead it is completely ignoring the decimal values. here is my code if I enter 2.0 + 5.0 it makes it 2 0 5 0 +. =(
import java.beans.Expression;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Infix2Postfix {
private static String grabDigits(String s, int start){
String num = "";
for(int i=start; i < s.length(); i++){
char ch = s.charAt(i);
if(Character.isDigit(ch))
num += ch;
else
return num;
}
return num;
}
private static Double apply(Double a, char op, Double b){
switch(op){
case '+' : return a + b;
case '-' : return a - b;
case '*' : return a * b;
case '/' : return b == 0 ? null : a / b;
default:
return null;
}
}
public static Double evalPostfix(String expr){
Stack<Double> s = new Stack<Double>();
for(int i=0; i<expr.length(); ){
char ch = expr.charAt(i);
if(Character.isDigit(ch)){
String numStr = grabDigits(expr, i);
i += numStr.length();
Double value;
if(isColmn(numStr)){
value = getvaluefromcolmn(numStr);
}else{
value = Double.parseDouble(numStr);
}
s.push(value);
}
else {
if(isOp(ch)){
if(s.size() < 2) return null;
Double b = s.pop(); // right arg
Double a = s.pop(); // left arg
s.push(apply(a, ch, b));
}
else if(!Character.isWhitespace(ch))
return null;
i++; // consume individual char
}
}
if(s.size() != 1) return null;
return s.pop();
}
private static Double getvaluefromcolmn(String numStr) {
// TODO Auto-generated method stub
return null;
}
private static boolean isColmn(String numStr) {
// TODO Auto-generated method stub
return false;
}
private static int prec(char op){
switch(op){
case '+' :
case '-' :
return 0;
case '*' :
case '/' :
return 1;
default:
return -1;
}
}
private static boolean isOp(char ch){
return prec(ch) != -1;
}
public static String infix2postfix(String expr) {
Stack<Character> s = new Stack<Character>();
String pExpr = "";
int numOperands = 0;
int numOperators = 0;
for(int i=0; i<expr.length(); i++){
char ch = expr.charAt(i);
if(Character.isDigit(ch)){
pExpr += " " + ch;
// could have used the grabDigits method here ...
while(i+1 < expr.length() && Character.isDigit(expr.charAt(i+1))){
pExpr += expr.charAt(i+1);
i++;
}
numOperands++;
}
else if (ch == '(')
s.push(ch);
else if (ch == ')'){
while(!s.empty() && s.peek() != '('){
pExpr = pExpr + " " + s.pop() + " ";
numOperators++;
}
if(s.empty())
return "no matching open paren";
if(numOperators >= numOperands)
return "too many operators";
s.pop();
}
else if(isOp(ch)){
// pop operators with same or higher precedence
while(!s.empty() && isOp(s.peek()) && prec(s.peek()) >= prec(ch)){
pExpr = pExpr + " " + s.pop();
numOperators++;
}
if(numOperators >= numOperands)
return "too many operators";
s.push(ch);
}
// else white space - do nothing
}
while(!s.empty()){
char op = s.pop();
if(!isOp(op))
return "error";
pExpr += " " + op;
}
return pExpr;
}
public static void exp(String expr, ArrayList<ArrayList<Comparable<?>>> entries){
expr.replace("(", " ( ");
expr.replace(")", " ) ");
expr.replace("+", " + ");
expr.replace(" - ", " - ");
expr.replace("/", " / ");
expr.replace("*", " * ");
System.out.println("infix: " + expr);
System.out.println("this is at expreesion after replacing "+ expr);
System.out.println("postfix: " + infix2postfix(expr));
System.out.println("--------");
}
public static void main(String [] args){
Scanner kbd = new Scanner(System.in);
// ArrayList<int> tst;
ArrayList<Integer> tst2;
System.out.print("> ");
while(kbd.hasNextLine()){
String expr = kbd.nextLine();
expr = expr.replaceAll("\\s+","");
System.out.println(expr);
Pattern pattern = Pattern.compile("\\s+");
Matcher matcher = pattern.matcher(expr);
boolean check = matcher.find();
String str = matcher.replaceAll(" ");
expr = expr.replace("(", " ( ");
expr =expr.replace(")", " ) ");
expr =expr.replace("+", " + ");
expr =expr.replace("-", " - ");
expr =expr.replace("/", " / ");
expr =expr.replace("*", " * ");
String[] exprArray = expr.split(" ");
System.out.println(str+ " this is expr "+exprArray[1]);
System.out.println(expr);
ArrayList<ArrayList<Comparable<?>>> entries = null;
String pExpr = infix2postfix(expr);
//System.out.println(evalPostfix(expr));
System.out.println(" postfix version: " + pExpr);
System.out.println(" eval(\"" + pExpr + "\"): " + evalPostfix(pExpr));
System.out.print("> ");
}
}
}
I didn't check your code in detail but the following line
while(i+1 < expr.length() && Character.isDigit(expr.charAt(i+1))) ...
looks like you are parsing only digits but not '.' for each expression.
The same holds true for your method grabDigits.
By stopping at the first non-digit you are stopping at the decimal point, and therefore ignoring both it and everything after it.
Don't convert strings to doubles with your own code, use Double.parseDouble().

Categories