Having trouble casting a stack object number to int (Java) - casting

I'm writing a program that converts an expression from infix to postfix. I have the conversion part down but when it comes to evaluating the postfix expression, I run into problems with converting from char to int using the stack.
I keep getting the error: "Exception in thread "main" java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Integer"
It might be in this part of the code below where the problem is but I'm not sure:
Integer x1 = (Integer)stack2.pop();
Integer x2 = (Integer)stack2.pop();
Thank you!
public class Calc {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Please enter your infix expression: ");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String postfix = "";
Stack<Character> stack = new Stack<Character>();
for(int i = 0; i < input.length(); i++){
char subject = input.charAt(i);
if (subject == '*'||subject == '+'||subject == '-'||subject == '/'){
while ((stack.empty() == false) && (order(stack.peek()) >= order(subject)))
postfix += stack.pop() + " ";
stack.push(subject);
}
else if(subject == '(')
{
stack.push(subject);
}
else if(subject == ')')
{
while(stack.peek().equals('(') == false){
postfix += stack.pop() + " ";
}
stack.pop();
}
else{
if((Character.isDigit(subject) == true) && ((i + 1) < input.length()) && (Character.isDigit(input.charAt(i+1)) == true))
{
postfix += subject;
}
else if(Character.isDigit(subject))
{
postfix += subject + " ";
}
else
{
postfix += subject;
}
}
}
postfix += stack.pop();
System.out.println("Your post-fix expression is: " + postfix);
char subject2;
int yeah;
Stack stack2 = new Stack();
for (int j = 0; j < postfix.length(); j++){
subject2 = postfix.charAt(j);
if(Character.isDigit(subject2) == true){
stack2.push(subject2);
}
if(subject2 == ' '){
continue;
}
else{
Integer x1 = (Integer)stack2.pop();
Integer x2 = (Integer)stack2.pop();
if (subject2 == '+'){
yeah = x1 + x2;
}
if (subject2 == '-'){
yeah = x1 - x2;
}
if (subject2 == '*'){
yeah = x1 * x2;
}
if (subject2 == '/'){
yeah = x1 / x2;
}
else {
yeah = 0;
}
}
}
yeah = (int) stack2.pop();
System.out.println("The result is:" + yeah);
}
static int order(char operator)
{
if(operator == '+' || operator =='-')
return 1;
else if(operator == '*' || operator == '/')
return 2;
else
return 0;
}
}

You can solve this by casting to int. Note that int and Integer are not the same:
Integer x1 = (int) stack2.pop();
Integer x2 = (int) stack2.pop();

no casting is necessary by using type-information
Stack<Integer> stack2 = new Stack<Integer>();
…
if(Character.isDigit(subject2) == true){
stack2.push( Character.getNumericValue( subject2 ) );
}
…
to prevent an empty stack exception I'd prefer poll over pop
so it is easier to check an error condition
eg. if( x1 == null ) System.err.println( "Your error message" );
Deque<Integer> stack2 = new ArrayDeque<Integer>();
…
Integer x1 = stack2.poll();
Integer x2 = stack2.poll();
…
btw: the program is syntactically wrong, because it puts only one value on the stack

Related

string subscript out of range error when assigning variable to function

In order to become more familiar with cpp I began making a program that takes the derivative of simple polynomials using the power rule. So far, it is working fine for polynomials such as 5x^2+4x. However, if the polynomial contains a constant (like 5x + 3) I get a string subscript out of range error. I used the debugger and found the error triggers on line 33 (std::string term = differentiateTerm(*iter);). I'm not exactly sure what I'm doing wrong here and I would appreciate any help.
Full code:
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> terms;
std::vector<std::string>::const_iterator iter;
std::string takeDerivative(std::string expression);
void separateTerms(std::string expression);
std::string differentiateTerm(std::string inputTerm);
int main()
{
std::string userExpression;
std::cout << "Enter a polynomial.\n";
std::cin >> userExpression;
std::string outputExpression = takeDerivative(userExpression);
std::cout << "The derivative of your expression is: " + outputExpression;
return 0;
}
std::string takeDerivative(std::string expression)
{
std::string derivative;
separateTerms(expression);
for (iter = terms.begin(); iter != terms.end(); iter++)
{
std::string term = differentiateTerm(*iter);
if (iter - terms.begin() == 0)
{
derivative = term;
}
else
{
derivative += "+" + term;
}
}
return derivative;
}
void separateTerms(std::string expression)
{
int previousSign = 0;
bool firstTerm = true;
for (int i = 0; i < expression.size() + 1; i++)
{
if (expression[i] == '+' || expression[i] == '-')
{
if (firstTerm)
{
terms.push_back(expression.substr(0, i));
firstTerm = false;
previousSign = i;
}
else
{
terms.push_back(expression.substr(previousSign + 1, i - previousSign - 1));
previousSign = i;
}
}
else if (i == expression.size())
{
if (firstTerm)
{
terms.push_back(expression.substr(previousSign, i));
}
else
{
terms.push_back(expression.substr(previousSign + 1, i - previousSign));
}
}
}
}
std::string differentiateTerm(std::string inputTerm)
{
std::string outputTerm;
int coefficient = 1;
int exponent = 1;
int varPos = inputTerm.find('x');
if (inputTerm[varPos] == std::string::npos)
{
outputTerm = "0";
return outputTerm;
}
else {
if (inputTerm[varPos - 1] != std::string::npos)
{
coefficient = std::stoi(inputTerm.substr(0, varPos));
}
if (inputTerm[varPos + 1] == '^')
{
if (inputTerm[varPos + 2] != std::string::npos)
{
exponent = std::stoi(std::string(1, inputTerm[varPos + 2]));
}
}
}
coefficient = coefficient * exponent;
exponent--;
if (exponent <= 0)
{
outputTerm = std::to_string(coefficient);
}
else if (exponent == 1)
{
outputTerm = std::to_string(coefficient) + "x";
}
else
{
outputTerm = std::to_string(coefficient) + "x^" + std::to_string(exponent);
}
return outputTerm;
}
You're not checking the return value from find correctly in differentiateTerm. This causes inputTerm[varPos] to access out of bounds.
The correct check is
if (varPos == std::string::npos)
In the subsequent if statements, since you have a valid subscript in varPos, you should check that against the size of the string. So you'd have if (varPos > 0), if (varPos < inputTerm.size() - 1), etc.

c++ Getting wrong calculation from a function

This is my code of a function. In main i check if temperature is in kelvin or fahrenheit. When I get temp_enota = 'F' from main ( I do because I checked with debugging), and temp = 116 for some reason function returns 0 when it should be around 46. Any ideas why? It works fine for kelvins.
float pretvorbaTemp(char temp_enota, float temp) {
if (temp_enota == 'K') {
temp = temp - 273.15;
}
else if (temp_enota == 'F') {
temp = (temp - 32) * (5 / 9);
}
return temp;
}
calling from main function
if (temp >= 283 && temp <= 323) {
temp_enota = 'K';
zacasna = 1;
cout << "Vnesena temperatura je v K, kar je enako "<<pretvorbaTemp(temp_enota, temp)<<" C" << endl;
}
else if (temp <= 122 && temp >= 50) {
temp_enota = 'F';
zacasna = 1;
cout << "Vnesena temperatura je v F, kar je enako "<<pretvorbaTemp(temp_enota, temp)<<" C" << endl;
}
else if (temp >= -10 && temp < 50) {
temp_enota = 'C';
zacasna = 1;
cout << "Vnesena temperatura je v C" << endl;
}
else {
zacasna = 0;
zacasna2 = 1;
}
The reason you get 0 is because the expression
5/9
will evaluate to 0 as these are two integer values, thus the compiler generates the code to do an integer division.
Just change to
5./9
to force floating point.
Do this:
float pretvorbaTemp(char temp_enota, float temp) {
if (temp_enota == 'K') {
temp = temp - 273.15;
}
else if (temp_enota == 'F') {
temp = (temp - 32.0) * (5.0 / 9.0);
}
return temp;
}
Here temp = (temp - 32) * (5 / 9); the values are int. You need to use them as float.

Prime checker doesn't include some multipliers of the number 10

I need to make a program that will check whether or not the number typed in (a) and its mirrored self (a1) are both prime numbers. I got it to work up to the point where I input a multiplier of 10, in which case it declares it as a prime number, which it clearly isn't.
I've already tried setting the condition:
if ( a % 10 = 0 ) {//declare it as non prime}
After having done that, I would always get a return value of 0 after entering the number. Also tried declaring :
if ( a == 1 ) {//declare it as a non prime}
which fixed it for multipliers of 10 up to 100, but the rest would give me the previously stated error.
My go at it:
#include <iostream>
using namespace std;
int main() {
int a, a1, DN;
cin >> a;
DN = a;
a1 = 0;
for (; a != 0;) {
a1 *= 10;
a1 = a1 + a % 10;
a /= 10;
}
int este_prim, i, este_prim2;
este_prim = 1;
i = 2;
este_prim2 = 1;
while (i < DN && i < a1) {
if (DN % i == 0) {
este_prim = 0;
}
++i;
}
if (a1 > i && a1 % i == 0) {
este_prim2 = 0;
}
++i;
if (a == 1) {
este_prim = 0;
}
if (a1 == 1) {
este_prim2 = 0;
}
if (este_prim2 == 1 && este_prim == 1) {
cout << "DA";
} else {
cout << "NU";
}
return 0;
}
I'm a complete newbie at this so any help would be appreciated. Cheers!
Your loop checks if DN is prime, but it doesn't check if a1 is prime. And this block of code is something I do not understand.
if (a1 > i && a1 % i == 0) {
este_prim2 = 0;
}
So just remove that.
Use this worthy helper function to detect if a positive number is prime:
bool isPrime(int x)
{
if (x <= 1)
return false;
// 2 is the only even prime
if (x == 2)
return true;
// any other even number is not prime
if ((x % 2) == 0)
return false;
// try dividing by all odd numbers from 3 to sqrt(x)
int stop = sqrt(x);
for (int i = 3; i <= stop; i += 2)
{
if ((x % i) == 0)
return false;
}
return true;
}
And then your code to detect if DN and it's mirror, a1 are both prime is this:
int main() {
int a, a1, DN;
cin >> a;
DN = a;
a1 = 0;
for (; a != 0;) {
a1 *= 10;
a1 = a1 + a % 10;
a /= 10;
}
bool este_prim, este_prim2;
este_prim = isPrime(DN);
este_prim2 = isPrime(a1);
if (este_prim2 && este_prim) {
cout << "DA";
} else {
cout << "NU";
}
}

prefix notation c++, segmentation fault (stack and queue)

I am trying to figure out why I get segmentation fault, and my guess is that it is in my recursive function, which simplifies a prefix notation operation.
For example:
"m + 4 4" Returns: "+ m 8"
During testing I get a segmentation fault signal:
Exited with signal 11 (SIGSEGV)
I believe though that the problem lies in my recusive function "Operate"
string Operate(stack<string> &S, queue<string> &Q)
{
S.push(Q.front());
Q.pop();
std::string::size_type sz;
string result = "";
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (Q.empty() == false)
{
S.push(Q.front());
Q.pop();
if (IsOperator(S.top()) == true)
{
S.push(Operate(S, Q));
}
if (S.size() < 3)
return "wrong input";
string arg1 = S.top();
S.pop();
string arg2 = S.top();
S.pop();
string oper = S.top();
S.pop();
if (StringIsDigit(arg1) && StringIsDigit(arg2))
{
int a = stoi(arg1, &sz);
int b = stoi(arg2, &sz);
char o = oper.at(0);
int c = 0;
if (o == '+')
c = b + a;
else if (o == '-')
c = b - a;
else if (o == '*')
c = b * a;
else
return "e";
result = to_string(c);
}
else
result = oper + " " + arg2 + " " + arg1;
}
else
{
result = S.top();
S.pop();
}
return result;
}
or in the function StringIsDigit:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
Link to the whole program code:
https://pastebin.com/04pfE55N
The answer was quite simple, my error: SEGFAULT was as many pointed out for me error in reading from memory, segmentation fault, wiki.
When did the segfault occur?
It was when my function StringIsDigit() tried to figure out if negative values over 2 characters was an integer. In the "if statement, when checking if the string was indeed an integer, say -100", I continued to read the string until I reached the end of the arg string, but with arg.at(i + 1). Leading to the code trying to access memory outside the string array.Thanks Struthersneil for finding this flaw!
Please look at my old StringIsDigit() to find out the of by one value error I made:
bool StringIsDigit(string arg)
{
bool result = true;
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(i + 1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}
The solution
The solution I want to make sure that the string was an integer since my algorithm supports expressions, such as x+3. This means that I need to iterate through the string is call isdigit() on every character in the string array. Though '-' is not an integer, '-' is needed obviously to express a negative integer, so I made a flawed check as you can see in my old StringIsDigit(). Instead of using that conditional if statement, I checked if the first character '-' and the second is not a whitespace ' ', and then I just let the isdigit() function do the rest of the work.
bool StringIsDigit(string arg)
{
bool result = true;
//I only need to check if the first is a '-' char and
//the next char is not ' '.
for (int i = 0; i < arg.size() && result == true; i++)
{
if ((arg.size() != 1) && (arg.at(0) == '-') && (arg.at(1) != ' '))
i++;
else
result = isdigit(arg.at(i));
}
return result;
}

Algorithm to calculate sum of LUCKY FACTOR in given range

Problem Statement :-
A number is given, N, which is given in binary notation, and it
contains atmost 1000000 bits. You have to calculate the sum of LUCKY
FACTOR in range from 1 to N (decimal notation).
Here, LUCKY FACTOR means, (after converting into binary representation) if
rightmost or leftmost 1's neighbour is either 0 or nothing(for
boundary bit).
EDITED :-
Means if rightmost one's left neighbour is 0, means it count as a
LUCKY FACTOR, simlarly in the left side also
Example,
5 == 101, LUCKY FACTOR = 2.
7 == 111, LUCKY FACTOR = 0.
13 == 1101, LUCKY FACTOR = 1.
16 == 1110, LUCKY FACTOR = 0.
0 == 0, LUCKY FACTOR = 0.
Answer must be in binary form
I am totally stuck, give me a hint.
My code
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
//#include<iostream>
using namespace std;
vector<string> pp(10000001);
string add(string a, string b) {
if(b == "") return a;
string answer = "";
int c = 0;
int szeA = a.size() - 1;
int szeB = b.size() - 1;
while(szeA >= 0 || szeB >= 0) {
answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer;
c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) );
szeA--;
szeB--;
}
if(c) answer = '1' + answer;
return answer;
}
string subtract(string a, string b) {
int sze = a.size() - b.size();
while(sze--) b = '0' + b;
sze = a.size();
for(int i = 0; i < sze; i++) {
if(b[i] == '1') b[i] = '0';
else b[i] = '1';
}
if(b[sze-1] == '0') {
b[sze-1] = '1';
}
else {
int i = sze-1;
while(i >= 0 && b[i] == '1') {
b[i] = '0';
i--;
}
if(i >= 0) b[i] = '1';
else b = '1' + b;
}
b = add(a, b);
b.erase(b.begin() + 0);
//b[0] = '0';
while(b[0] == '0') b.erase(b.begin() + 0);
return b;
}
string power(int index) {
if(index < 0) return "";
string answer = "";
while(index--) {
answer = '0' + answer;
}
answer = '1' + answer;
return answer;
}
string convert(long long int val) {
int divisionStore=0;
int modStore=0;
string mainVector = "";
do {
modStore=val%2;
val=val/2;
mainVector = (char)(modStore+48) + mainVector;
}while(val!=0);
return mainVector;
}
string increment(string s) {
int sze = s.size()-1;
if(s[sze] == '0') {
s[sze] = '1';
return s;
}
while(sze >= 0 && s[sze] == '1') {
s[sze] = '0';
sze--;
}
if(sze >= 0) s[sze] = '1';
else s = '1' + s;
return s;
}
main() {
int T;
char s[1000001];
string answer;
scanf("%d", &T);
for(int t = 1; t <= T; t++) {
int num;
answer = "1";
int bitComeEver = 0;
int lastBit = 0;
scanf("%s", s);
int sze = strlen(s);
// I used below block because to avoid TLE.
if(sze > 3300) {
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", '1');
printf("\n");
//continue;
}
else {
if(pp[sze-1] != "") answer = pp[sze-1];
else {
pp[sze-1] = power(sze-1);
answer = pp[sze-1];
}
answer = subtract(answer, convert(sze-1));
////////////////////////////
//cout << answer << endl;
for(int i = 1; i < sze; i++) {
if(s[i] == '1') {
if(s[1] == '0') {
num = sze-i-1;
if(num > 0) {
if( pp[num-1] == "") {
pp[num-1] = power(num-1);
}
if(pp[num+1] == "") {
pp[num+1] = power(num+1);
}
answer = add(answer, subtract(pp[num+1], pp[num-1]));
if(lastBit) answer = add(answer, "1");
//else answer = increment(answer);
//cout << "\t\t" << answer << endl;
}
else{
int inc;
if(lastBit) inc = 2; //answer = add(answer, "10");
else inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 2;
else inc += 1;
if(inc == 2) answer = add(answer, "10");
else if(inc == 3) answer = add(answer, "11");
else answer = add(answer, "100");
}
}
else {
if(num > 0) {
if(pp[num-1] != "") pp[num-1] = power(num-1);
answer = add(answer, pp[num-1]);
}
else {
int inc = 0;
if(lastBit) inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 1;
answer = add(answer, convert(inc));
}
}
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
}
}
if(s[sze-1] == '0') {
if(lastBit) {
if(s[1] == '0') {
answer = add(answer, "10");
}
else answer = increment(answer);
}
else if(s[1] == '0'){
answer = increment(answer);
}
}
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", answer[i]);
printf("\n");
}
}
return 0;
}
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2:
10.............01
Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4).
So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4)
(ofcourse this is assuming k >= 4)
What's more, you do not need to calculate this number since it will be of the form 10000000.
If the number n is 11010010. Then 8 bit numbers less than n shall be of form:
10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n
.
I leave the rest for you.