Java - Program outputs and else statement for no reason? - if-statement

I have a really simple quadratic formula code I wrote a while ago and got back to. It runs fine, but it outputs my final else statement even though it shouldn't!
import javax.swing.JOptionPane;
public class quadFormGUI {
public void quadForm(){
String aNumI = JOptionPane.showInputDialog("What is your 'A' variable?");
String bNumI = JOptionPane.showInputDialog("What is your 'B' variable?");
String cNumI = JOptionPane.showInputDialog("What is your 'C' variable?");
double aNum = Double.parseDouble(aNumI);
double bNum = Double.parseDouble(bNumI);
double cNum = Double.parseDouble(cNumI);
double oneAns = (bNum * bNum) + (-aNum * cNum * 4);
if (oneAns < 0){
JOptionPane.showMessageDialog(null,"The equation does not have a solution", "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
}else{
double twoAns = (double) Math.sqrt(oneAns);
double threeAns = -bNum + twoAns;
double xOne = threeAns/(2*aNum);
double fourAns = (bNum * bNum) + (-aNum * cNum * 4);
double fiveAns = (double) Math.sqrt(fourAns);
double sixAns = -bNum - fiveAns;
double xTwo = sixAns/(2*aNum);
JOptionPane.showMessageDialog(null,"X1 is " + xOne + " & X2 is " +xTwo, "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
xOne = xOne * -1;
xTwo = xTwo * -1;
if (xOne < 0 && xTwo < 0){
JOptionPane.showMessageDialog(null,aNum +"(X " + xOne + ") (X " + xTwo + ")", "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
}else if (xOne < 0 && xTwo > 0){
JOptionPane.showMessageDialog(null,aNum +"(X " + xOne + ") (X + " + xTwo + ")", "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
}else if (xOne > 0 && xTwo < 0){
JOptionPane.showMessageDialog(null,aNum +"(X + " + xOne + ") (X " + xTwo + ")", "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
}else if (xOne > 0 && xTwo > 0){
JOptionPane.showMessageDialog(null,aNum +"(X + " + xOne + ") (X + " + xTwo + ")", "Quadratic Formula" , JOptionPane.PLAIN_MESSAGE);
}else{
System.out.println("Wrong");
}
}
}
}
It always outputs "Wrong" no matter what!

If you are seeing "Wrong" on the console, your program flow is going to the last "else" part. This means that either xOne or xTwo or both are 0. The only way xOne or xTwo can be zero is if you enter 0s for a and c. There is also another possibility that in your JOptionPane showInputBox, you are not pressing Ok button after entering a value; you might be pressing the cancel button in which case a null value will be returned and stored in your String variables aNumI, bNumI and cNumI. Except for these 2 cases, your program cannot go to the else part. I executed your very program in an online IDE and it is not going to the else part. The only difference is that I am not using JOptionPane.
Try to print or debug the values of aNumI, bNumI and cNumI right after the input boxes are closed. I am sure they will be either null or have '0'. Let me know what you find out.

Yes yes, sorry, I was incorrect. Now thinking back on it, why was I checking for X to be 0? Anyway, the program works fine, I was just always inputting A = 0, B = -3, C = 0. I fixed it, it works now.

Related

Finding the mean of all number in a range given by the user

Program is supposed to allow the user to input 2 integers and find the mean of all the integers between (and including) the two given by the user.
#include <iostream>
using namespace std;
int main()
{
int value1, value2;
int total = 0;
int number = 1; // the amount of numbers
float mean;
cout << "Please enter two positive integers separated by a space" << endl;
cin >> value1; cin >> value2;
if (value1 > 0 && value2 > 0)
{
for (int total = value1; total <= value2; total++)
{
mean = static_cast<float>(total) / number;
}
cout << "The mean average of the numbers between and including "
<< value1 << " and " << value2
<< " is " << mean << endl;
}
else
{
cout << "Invalid input - integer must be positive" << endl;
}
return 0;
}
Currently mean just ends up repeating the second number. How far off am I here?
You don't need a for-loop. You can compute mean as:
mean = (value1 + value2)/2.0;
Done.
Otherwise, the bugs in your program are as follows:
First number is only ever assigned the value 1.
Second, you are redeclaring total as a for loop variable as well as an outer variable. You only need to declare it once. The compiler should have warned you.
Third:
for (int total = value1; total <= value2; total++)
{
mean = static_cast<float>(total) / number;
}
In the above you are continually reassigning a new value to mean on each iteration instead of letting it accumulate. Also mean is never initialized before the for loop. Probably want to set it to zero.
Finally, you're not handling the case where a user enters a bigger number for value1 than value2.
I think you really meant this:
if (value1 > value2)
{
int tmp = value2;
value2 = value;
value1 = tmp;
}
number = value2-value1+1;
mean = 0.0f;
for (total = value1; total <= value2; total++)
{
mean += static_cast<float>(total) / number;
}
But again, unless my math is off, the above is simplified to:
mean = (value1+value2)/2.0;
I've edited my answer and undeleted it to explain why it sucked and why selbie's answer is correct.
As selbie pointed out, the mean of all integers in [m, n] is (m + n)/2.
To undestand why, let's step through my previously unnecessary complicated answer.
The sum of all integers in (0, n] is n*(n + 1)/2.
Assuming that n > m, to know the sum of all the integers in (m, n] just subtract the sum of all the integers in (0, m], i.e.: (n*(n + 1)/2 - m*(m + 1)/2)
To know the sum of all integers in [m, n], we must use m1 = m - 1
Once you know the sum the mean is simply sum/(n - m1)
It works, but it sucks because the right answer is way easier.
The nice thing is that from my inefficient answer is possible to derive the good one.
Let's consider
n = m + k
m1 = m - 1
and replace them in the equation (n*(n + 1)/2 - m1*(m1 + 1)/2)/(n - m1)
I factorized both / 2 and replaced them with * 0.5 outside.
The resulting sequence of simplifications is
( ( (m + k)*(m + k + 1) - (m - 1)*(m - 1 + 1) ) * 0.5 ) / ( m + k - m + 1)
( ( m2 + km + km + k2 + m + k - m2 + m ) * 0.5 ) / ( k + 1 )
( ( 2km + 2m + k2 + k ) * 0.5 ) / ( k + 1 )
( ( 2m(k + 1) + k(k + 1) ) * 0.5 ) / ( k + 1 )
( (2m + k) * (k + 1) * 0.5 ) / ( k + 1 )
( 2m + k ) * 0.5
( m + k + m ) / 2
( m + n ) / 2
Which is exactly the average of value1 and value2

Substrings of equal length comparison using hashing

On an assignment that I have, for a string S, I need to compare two substrings of equal lengths. Output should be "Yes" if they are equal, "No" if they are not equal. I am given the starting indexes of two substrings (a and b), and the length of the substrings L.
For example, for S = "Hello", a = 1, b = 3, L = 2, the substrings are:
substring1 = "el" and substring2 = "lo", which aren't equal, so answer will be "No".
I think hashing each substring of the main string S and writing them all to memory would be a good aproach to take. Here is the code I have written for this (I have tried to implement what I learned about this from the Coursera course that I was taking):
This function takes any string, and values for p and x for hashing thing, and performs a polynomial hash on the given string.
long long PolyHash(string str, long long p, int x){
long long res = 0;
for(int i = str.length() - 1; i > -1; i--){
res = (res * x + (str[i] - 'a' + 1)) % p;
}
return res;
}
The function below just precomputes all hashes, and fills up an array called ah, which is initialized in the main function. The array ah consists of n = string length rows, and n = string length columns (half of which gets wasted because I couldn't find how to properly make it work as a triangle, so I had to go for a full rectangular array). Assuming n = 7, then ah[0]-ah[6] are hash values for string[0]-string[6] (meaning all substrings of length 1). ah[7]-ah[12] are hash values for string[0-1]-string[5-6] (meaning all substrings of length 2), and etc. until the end.
void PreComputeAllHashes(string str, int len, long long p, int x, long long* ah){
int n = str.length();
string S = str.substr(n - len, len);
ah[len * n + n - len] = PolyHash(S, p, x);
long long y = 1;
for(int _ = 0; _ < len; _++){
y = (y * x) % p;
}
for(int i = n - len - 1; i > -1; i--){
ah[n * len + i] = (x * ah[n * len + i + 1] + (str[i] - 'a' + 1) - y * (str[i + len] - 'a' + 1)) % p;
}
}
And below is the main function. I took p equal to some large prime number, and x to be some manually picked, somewhat "random" prime number.
I take the text as input, initialize hash array, fill the hash array, and then take queries as input, to answer all queries from my array.
int main(){
long long p = 1e9 + 9;
int x = 78623;
string text;
cin >> text;
long long* allhashes = new long long[text.length() * text.length()];
for(int i = 1; i <= text.length(); i++){
PreComputeAllHashes(text, i, p, x, allhashes);
}
int queries;
cin >> queries;
int a, b, l;
for(int _ = 0; _ < queries; _++){
cin >> a >> b >> l;
if(a == b){
cout << "Yes" << endl;
}else{
cout << ((allhashes[l * text.length() + a] == allhashes[l * text.length() + b]) ? "Yes" : "No") << endl;
}
}
return 0;
}
However, one of the test cases for this assignment on Coursera is throwing an error like this:
Failed case #7/14: unknown signal 6 (Time used: 0.00/1.00, memory used: 29396992/536870912.)
Which, I have looked up online, and means the following:
Unknown signal 6 (or 7, or 8, or 11, or some other).This happens when your program crashes. It can be
because of division by zero, accessing memory outside of the array bounds, using uninitialized
variables, too deep recursion that triggers stack overflow, sorting with contradictory comparator,
removing elements from an empty data structure, trying to allocate too much memory, and many other
reasons. Look at your code and think about all those possibilities.
And I've been looking at my code the entire day, and still haven't been able to come up with a solution to this error. Any help to fix this would be appreciated.
Edit: The assignment states that the length of the input string can be up to 500000 characters long, and the number of queries can be up to 100000. This task also has 1 second time limit, which is pretty small for going over characters one by one for each string.
So, I did some research as to how I can reduce the complexity of this algorithm that I have implemented, and finally found it! Turns out there is a super-simple way (well, not if you count the theory involved behind it) to get hash value of any substring, given the prefix hashes of the initial string!
You can read more about it here, but I will try to explain it briefly.
So what do we do - We precalculate all the hash values for prefix-substrings.
Prefix substrings for a string "hello" would be the following:
h
he
hel
hell
hello
Once we have hash values of all these prefix substrings, we can collect them in a vector such that:
h[str] = str[0] + str[1] * P + str[2] * P^2 + str[3] * P^3 + ... + str[N] * P^N
where P is any prime number (I chose p = 263)
Then, we need a high value that we will take everything's modulo by, just to keep things not too large. This number I will choose m = 10^9 + 9.
First I am creating a vector to hold the precalculated powers of P:
vector<long long> p_pow (s.length());
p_pow[0] = 1;
for(size_t i=1; i<p_pow.size(); ++i){
p_pow[i] = (m + (p_pow[i-1] * p) % m) % m;
}
Then I calculate the vector of hash values for prefix substrings:
vector<long long> h (s.length());
for (size_t i=0; i<s.length(); ++i){
h[i] = (m + (s[i] - 'a' + 1) * p_pow[i] % m) % m;
if(i){
h[i] = (m + (h[i] + h[i-1]) % m) % m;
}
}
Suppose I have q queries, each of which consist of 3 integers: a, b, and L.
To check equality for substrings s1 = str[a...a+l-1] and s2 = str[b...b+l-1], I can compare the hash values of these substrings. And to get the hash value of substrings using the has values of prefix substrings that we just created, we need to use the following formula:
H[I..J] * P[I] = H[0..J] - H[0..I-1]
Again, you can read about the proof of this in the link.
So, to address each query, I would do the following:
cin >> a >> b >> len;
if(a == b){ // just avoid extra calculation, saves little time
cout << "Yes" << endl;
}else{
long long h1 = h[a+len-1] % m;
if(a){
h1 = (m + (h1 - h[a-1]) % m) % m;
}
long long h2 = h[b+len-1] % m;
if(b){
h2 = (m + (h2 - h[b-1]) % m) % m;
}
if (a < b && h1 * p_pow[b-a] % m == h2 % m || a > b && h1 % m == h2 * p_pow[a-b] % m){
cout << "Yes" << endl;
}else{
cout << "No" << endl;
}
}
Your approach is very hard and complex for such a simple task. Assuming that you only need to do this operation once. You can compare the substrings manually with a for loop. No need for hashing. Take a look at this code:
for(int i = a, j = b, counter = 0 ; counter < L ; counter++, i++, j++){
if(S[i] != S[j]){
cout << "Not the same" << endl;
return 0;
}
}
cout << "They are the same" << endl;

How to calculate pi with 3 decimals precision in C++?

hey guys I am trying to calculate pi using this formula:
pi = 4 ยท [ 1 โ€“ 1/3 + 1/5 โ€“ 1/7 + 1/9 ... + (โ€“1)^n/(2n + 1) ]
yet i always get a zero for my output pi value and I am really confused as to where I had gone wrong. Here is my code:
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int n;
double b = 0;
char c = 'Y';
int s = 1;
while (c == 'Y') {
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
if (n != -1) {
c = 'Y';
for (int a = 1; a <= n; a++) {
s = -s;
b += 4 * (s/ (2 * a + 1));
}
cout << "The approximate value of pi using 1 term is:" << b << endl;
}
else {
c = 'N';
}
}
return 0;
}
In both C and C++, mathematical operations on integers result in an integer even if the result would be fractional in conventional mathematics. Change your int to a float or double and I suspect that it will work better.
The result is truncated to the integer value and has an integer type.
So for example: 2 / 4 results in 0 and 5 / 2 would result in 2.
NOTE if you perform an operation between a floating point value and an integer value, the result is a floating point value. So:
2.0 / 4 == 0.5
Your code seems to be complicated and int type is used in places where floating operations are expected.
Consider the following simplified example:
#include <cmath>
#include <iostream>
using namespace std;
int main()
{
int n = 0;
double b = 0;
double s = 1; // Tytpe is changed
while (n != -1) { // there is no need for char c
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
b = 0; // init b before starting the loop
s = 1; // the same for s (it can be -1 from the next user input)
// there is no need for if (n != -1) because for has condition
for (int a = 1; a <= n; a++) {
s = -s;
b += 4 * (s / (2.0 * a + 1));
}
cout << "The approximate value of pi using 1 term is:" << b << endl;
}
return 0;
}
IMPORTANT UPDATE:
To make your calculation correct (in terms of Leibniz's formula) I suggest the following changes in the for loop:
for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
b += 4.0 * (s / (a + 1.0));
s = -s; // change the sign for next calculation
}
and further, consider some kind of optimization
b = 0; // do not forget about reseting b to 0 before making sum
s = 1; // set 1 in the sign
for (int a = 0; a <= n; a+=2) { // start from 0 with step 2
b += s / (a + 1.0); // no multiplication on each iteration
s = -s; // because s was initialized with 1
}
b *= 4.0; // multiply once for the whole sum
UPDATE 2
For case if precision is really important for output, final snippet can be like:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int n = 0;
double b = 0;
double s = 1;
int prec = 0;
cout << "What precision should be used for output? (Value from 1 to 10): ";
while (prec< 1 || prec > 10)
{
cin >> prec;
}
while (true) {
cout << "Enter the value of the parameter 'n' in the Leibniz formula (or -1 to quit):" << endl;
cin >> n;
if (n == -1)
{
break; // go out the loop if user enter -1 (want to exit)
}
else if (n <= 0)
{
cout << "'n' have to be 1 or greater" << endl;
continue; // go to the next iteration to ask new 'n'
}
s = 1;
b = 1.0; // we can start from 1 (no need to claculate the first term) and make loop from 2
for (int a = 2; a < n*2; a+=2) { // start from 2 with step 2 (so n should be doubled)
s = -s; // change the sign for this iteration, because now loop started from a = 2
b += s / (a + 1.0);
}
b *= 4.0;
cout << "The approximate value of pi using 1 term is: " << setprecision(prec+1) << b << " (PI = " << M_PI << ")" << endl;
}
return 0;
}
Note:
In this version b initialized with 1.0 because the first item in the Leibniz series is always 1 (we can skip calculation, but we should change the logic for sign changes - make s = -1; or move s = -s; before summation - I choose the 2nd option).
Also I'am not sure what is "parameter 'n' in the Leibniz formula", so pay attention to condition of for loop - now (with a < n*2) it is correct for case if n is number of items in the Leibniz series to be calculated.
Along with doing integer math, you have a few other minor problems.
First, the formula is [1 - ...], not [0 - ...], so you need to initialize b to 1.0, not 0.
Second, it's supposed to be 4 * [...], but you're multiplying by 4 on every iteration of the loop, so you're getting `[0 - b1 * 4 + b2 * 4 -b3 * 4 ....].
You can distribute the multiplication if you want to, but if you do you'll need to distribute it correctly (e.g., the starting value of 1.0 would also need to be multiplied by 4).
Also note that you're not re-initializing correctly, so the second (and subsequent) times you attempt to re-compute the value, you'll get completely incorrect answers (until you fix more stuff).
You've been burned by integer division.
b += 4 * (s/ (2 * a + 1));
a is an int so the division result is an int.
A cast to double will fix it:
b += 4 * (s/ (2 * double(a) + 1));

string concatenation in c++

Previously, I was using append function to concatenate strings.
However, since doing so requires multiple lines of unnecessary codes, I wanted to try out '+' operator instead. Unfortunately, it didn't go well...
bool Grid::is_available(int x, int y) const
{
if (x < 0 || x >= dim[1] || y < 0 || y >= dim[0])
throw std::invalid_argument("is_available(" + x + ", " + y + "): Invalid coordinate input.");
return occupancy[x][y] == AVAILABLE;
}
The error that I got was "'+': cannot add two pointers" with the code C2110.
All the solutions for this problem said to concatenate one on each line.
Are there actually no way to concatenate multiple strings in C++ in one line? I had no problem with this in C# before.
You can use std::to_string() to convert your integers:
bool Grid::is_available(int x, int y) const
{
if (x < 0 || x >= dim[1] || y < 0 || y >= dim[0])
throw std::invalid_argument(
"is_available(" + std::to_string(x) + ", "
+ std::to_string(y) + "): Invalid coordinate input.");
return occupancy[x][y] == AVAILABLE;
}

How to use pointers and pointer aritmetic

: error C2064: term does not evaluate to a function taking 1 arguments
: error C2227: left of '->name' must point to class/struct/union/generic type
how do i fix this so this error doesn't happen
for(int index = 0; index < (numStudents); index++)
{
if (student(index + 1)->score >= 90 )
student(index + 1)->grade = 'A';
else if (student(index + 1)->score >= 80 )
student(index + 1)->grade = 'B';
else if (student(index + 1)->score >= 70 )
student(index + 1)->grade = 'C';
else if (student(index + 1)->score >= 60 )
student(index + 1)->grade = 'D';
else
student(index + 1)->grade = 'F';
}
heres the structure:
struct StudentType
{
string name;
int score;
char grade;
};
and here is the pointer :
StudentType* student;
My guess is that you need to do
student[index + 1]
instead of
student(index + 1)
You should really specify what is student so people can answer this question.
From your comment answers it appears student is a pointer. In that case student(index + 1) is not valid syntax. I think you mean student[index + 1].
Further critique - 1 based arrays in C are bad form. Consider starting at 0 like everyone else in C
Is students a method/function or an array? Perhaps this is what you mean:
for (int index = 0; index < numStudents; index++) {
// ensure that we don't go past the end of the student array
if (index + 1 == numStudents) break;
if (student[index + 1]->score >= 90) student[index + 1]->grade = 'A';
else if (student[index + 1]->score >= 80) student[index + 1]->grade = 'B';
else if (student[index + 1]->score >= 70) student[index + 1]->grade = 'C';
else if (student[index + 1]->score >= 60) student[index + 1]->grade = 'D';
else student[index + 1]->grade = 'F';
}
Though I don't understand why you are avoiding the first student (students[0]). You know arrays are zero-based, right? You could achieve the same effect without all of the 'index + 1' if you initialize the index variable to 1 instead of 0.
I'm pretty sure what it's trying to tell you is that the student function doesn't take just one argument. Since it couldn't actually call the function the second part of the error then tells you it can't be used to the left of ->
It's hard to say without more detail (specifically, what is student), but assuming student is a vector or array most likely you meant to say student[index + 1] instead of using the parentheses.