Displaying an equation in C++ - c++

I’m writing a formula to solve for the roots of a quadratic in C++. My output should begin with the equation such as
3x^2 +2x -3
Everything in my program is correct except for this part. My output has all plus signs followed by the coefficient. How can I get it to display minus (-) signs instead of + when a coefficient is negative? Any help is appreciated thanks!
Example code:
std::cout << a << “x^2” << “+” << b<< “x”
If b is negative it prints ax^2 + -3x but I need it to display ax^2 - 3x

std::cout << a << "x^2" << b >= 0? "+" : "" << b<< "x";
Use ternary operator to make sure "+" is only there when b is not negative.

Your problem with something like:
std::cout << a << "x^2" << "+" << b << "x";
is that you are always outputting a + followed by the b value, be it positive or negative (or zero for that matter). Consider a = 7, b = -42:
7x^2+-42x
As you've seen, these won't look nice for negative numbers. You could get rid of the + but then it would look bad for positive numbers. Consider a = 7, b = 42:
7x^242x
The following code shows a slightly different approach, where the coefficients are checked for sign and then the output is adjusted properly. It also handles arbitrary powers, though only down to zero, allows you to decide whether to print zero coefficients or not, and spaces the terms nicely:
#include <iostream>
#include <vector>
void outputEquation(const std::vector<int> &vec, bool showZeros = false) {
// Power counts down, first is to change
// formatting of first term.
auto power = vec.size() - 1;
auto first = true;
// Handle each coefficient.
for (const auto coeff: vec) {
// Select whether zero coefficients are shown.
if (coeff != 0 || showZeros) {
// Leading space on all but first term.
if (! first) std::cout << " ";
// Intelligently handle negative/non-negative.
if (coeff >= 0) {
// No leading '+' on first term,
// only print coefficient if not 1.
if (! first) std::cout << "+ ";
if (coeff != 1) std::cout << coeff;
} else {
// Output sign for negative, with space after
// if not first term. Then output |coeff|
// unless 1.
std::cout << "-";
if (! first) std::cout << " ";
if (coeff != -1) std::cout << -coeff;
}
// Output power, taking into account "x^1"
// and "x^0", which become "x" and "".
if (power > 1) {
std::cout << "x^" << power;
} else if (power == 1) {
std::cout << "x";
}
// First term done, adjust future behaviour.
first = false;
}
// Decrease power for next element.
--power;
}
// If no terms were output, just give 0.
if (first) {
std::cout << '0';
}
std::cout << '\n';
}
void outputEquation(int a, int b, int c, bool showZeros = false) {
// Just make a vector and call function above.
outputEquation({a, b, c}, showZeros);
}
// Test harness, adapt as necessary.
int main() {
outputEquation({ -4, 3, -2, 1, -1, 0, 4 });
outputEquation({ });
outputEquation({ 4 });
outputEquation({ 0 });
outputEquation({ 0, 1, 2 });
outputEquation({ 0, 0, 0, 0, 99, 0, 0, 0, 0 });
outputEquation({ 0, 0, 0, 0, 99, 0, 0, 0, 0 }, true);
outputEquation(1, 2, 3);
}
The first overloaded function is a general purpose one which you can augment with the second overload, meant specifically for quadratics. This outputs:
-4x^6 + 3x^5 - 2x^4 + x^3 - x^2 + 4
0
4
0
x + 2
9x^4
0x^8 + 0x^7 + 0x^6 + 0x^5 + 99x^4 + 0x^3 + 0x^2 + 0x + 0
x^2 + 2x + 3
but you can adjust the parameters for other possibilities.

Related

Getting coefficients from a string

I have a project to write a program that receives a polynomial string from the user up to the 5th power (ex. x^3+6x^2+9x+24) and prints out all the real and imaginary roots. The coefficients should be stored in a dynamic array.
The problem is getting these coefficients from the string. One of the coefficients can be a 0 (ex. 2x^2-18) so I can't store the coefficients from left to right by using an increment, because in this case a=2, b=-18, and c has no value, which is wrong.
Another problem is if the coefficient is 1, because in this case nothing will be written beside the x for the program to read (ex. x^2-x+14). Another problem is if the user adds a space, several, or none (ex. x ^3 +4x^ 2- 12 x + 1 3).
I have been thinking of pseudocode for a long time now, but nothing is coming to mind. I thought of detecting numbers from left to right and reading numbers and stopping at x, but the first and second problems occur. I thought of finding each x and then checking the numbers before it, but the second problem occurs, and also I don't know how big the number the user inputs.
Here is another Regex that you can use to get your coefficients after deleting whitespace characters:
(\d*)(x?\^?)(\d*)
It uses groups (indicated by the brackets). Every match has 3 groups:
Your coefficient
x^n, x or nothing
The exponent
If (1) is null (e.g. does not exist), it means your coefficient is 1.
If (2) and (3) are null, you have the last single number without x.
If only (3) is null, you have a single x without ^n.
You can try some examples on online regex sites like this one, where you can see the results on the right.
There are many tutorials online how to use Regex with C++.
You should normalize your input string, for example, remove all space then parse coefficients.
Let see my example. Please change it for your case.
#include <iostream>
#include <regex>
#include <iterator>
#include <string>
#include <vector>
#include <algorithm>
int main(int argc, char *argv[]) {
std::string input {argv[1]};
input.erase(remove_if(input.begin(), input.end(), isspace), input.end());
std::cout << input << std::endl;
std::vector<int> coeffs;
std::regex poly_regex(R"(\s*\+?\-?\s*\d*\s*x*\^*\s*\d*)");
auto coeff_begin = std::sregex_iterator(input.begin(), input.end(), poly_regex);
auto coeff_end = std::sregex_iterator();
for (std::sregex_iterator i = coeff_begin; i != coeff_end; ++i) {
std::smatch match = *i;
std::string match_str = match.str();
// std::cout << " " << match_str << "\n";
std::size_t plus_pos = match_str.find('+');
std::size_t minus_pos = match_str.find('-');
std::size_t x_pos = match_str.find('x');
if (x_pos == std::string::npos) {
std::cout << match_str.substr(plus_pos + 1) << std::endl;
} else if (x_pos == 0) {
std::cout << 1 << std::endl;
} else if (minus_pos != std::string::npos) {
if (x_pos - minus_pos == 1) std::cout << -1 << std::endl;
else std::cout << match_str.substr(minus_pos, x_pos - minus_pos) << std::endl;
}
else {
std::cout << match_str.substr(plus_pos + 1, x_pos - plus_pos - 1) << std::endl;
}
}
for (auto i: coeffs) std::cout << i << " ";
return 0;
}

myProgrammingLab Palindrome Challenge Using Recursion

I'm taking an Intro to Programming class and a good chunk of the material is drilled into our heads through myProgrammingLab. I'm having a little trouble with the concept of Recursion... It's sort of been hit or miss for me. This particular problem has me stumped. When I submit my code, it offers me
CTest1.cpp: In function 'bool isPalindrome(int*, int)':
CTest1.cpp:9: error: invalid conversion from 'int' to 'int*'
CTest1.cpp:9: error: initializing argument 1 of 'bool isPalindrome(int*, int)'"
as advice, which I can assure you is not very helpful. Lol
I think my main problem is when I get to the actual recursion. I'm aware that something's off, but.. If you could just point me in the right direction, I would very much appreciate it.
A 'array palindrome' is an array which, when its elements are reversed, remains the same (i.e., the elements of the array are same when scanned forward or backward)
Write a recursive, bool-valued function, isPalindrome, that accepts an integer -valued array , and the number of elements and returns whether the array is a palindrome.
An array is a palindrome if: the array is empty (0 elements ) or contains only one element (which therefore is the same when reversed), or the first and last elements of the array are the same, and the rest of the array (i.e., the second through next-to-last elements ) form a palindrome.
My code so far:
bool isPalindrome(int arr[], int n)
{
if (n == 0 || n == 1)
{
return true;
}
else if (arr[n-1] == isPalindrome(arr[((n-1) - n) +1 ], n))
{
return true;
}
else
{
return false;
}
}
Recursion mostly has three main components:
a stopping condition (when you reach an array size small enough to be a guaranteed palindrome (0 or 1)),
a computation step (e.g. to compare the first and last item of the array and determine whether it makes sense to continue) and
a data subset selection for the nested recursion call (e.g. an array of size n - 2, excluding the first and last characters, which we already compared and found “palindrome-worthy”).
The three components in code:
bool isPalindrome(int arr[], size_t n) {
return n < 2 || (
arr[0] == arr[n - 1] &&
isPalindrome(arr + 1, n - 2));
}
Of course you may want to test the function a bit (and do not forget to run it under valgrind as well):
#include <iostream>
int main() {
std::cout << isPalindrome((int[0]){}, 0) << std::endl;
std::cout << isPalindrome((int[1]){1}, 1) << std::endl;
std::cout << isPalindrome((int[2]){1, 1}, 2) << std::endl;
std::cout << isPalindrome((int[2]){2, 1}, 2) << std::endl;
std::cout << isPalindrome((int[2]){1, 2}, 2) << std::endl;
std::cout << isPalindrome((int[3]){1, 2, 1}, 3) << std::endl;
std::cout << isPalindrome((int[3]){2, 2, 2}, 3) << std::endl;
std::cout << isPalindrome((int[3]){2, 2, 1}, 3) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 1, 2}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 2, 1}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 2, 3, 2}, 4) << std::endl;
std::cout << isPalindrome((int[4]){2, 3, 2, 1}, 4) << std::endl;
std::cout << isPalindrome((int[4]){1, 3, 3, 1}, 4) << std::endl;
}
As a side note, this^^^ deadly struggle with arrays suggests that a different data type would be a much better choice. For example, std::string or std::vector can be initialized way easier, should be passed by reference and, as a bonus, STL containers carry size information with them. Additionally, you can use std::string_view for substrings and std::span for “subvectors” in your recursion, without copying the container over and over on each recursion level.
Here’s an example with std::string_view and three different implementations (one with recursion and two without recursion):
#include <iostream>
#include <string_view>
bool isPalindrome1(const std::string_view s) {
return s.size() < 2 || (
s[0] == s[s.size() - 1] &&
isPalindrome1(s.substr(1, s.size() - 2)));
}
bool isPalindrome2(const std::string_view s) {
const size_t end = s.size() / 2;
for (size_t i = 0; i < end; ++i)
if (s[i] != s[s.size() - i - 1])
return false;
return true;
}
bool isPalindrome3(const std::string_view s) {
auto b = s.begin();
const auto end = b + s.size() / 2;
auto e = s.rbegin();
for (; b < end; ++b, ++e)
if (*b != *e) return false;
return true;
}
int main() {
for (auto isPalindrome : {isPalindrome1,
isPalindrome2,
isPalindrome3}) {
std::cout << isPalindrome("") << std::endl;
std::cout << isPalindrome("a") << std::endl;
std::cout << isPalindrome("ab") << std::endl;
std::cout << isPalindrome("aa") << std::endl;
std::cout << isPalindrome("abc") << std::endl;
std::cout << isPalindrome("aba") << std::endl;
std::cout << isPalindrome("baab") << std::endl;
std::cout << isPalindrome("baba") << std::endl;
}
}
isPalindrome does not accept an int as a first argument. It accepts only an array, by doing this: arr[((n-1) - n) +1] you are feeeding it an int instead if an array of ints. This ((n-1) - n) +1 will evaluate to a “position” in the array, eg: arr[0] being the first element, your case an int.

C++ is calculating wrong

i have an inexplicable problem. Here is my code:
int result;
result = 0 * 2 ^ 1;
std::cout << result << std::endl;
The result of this calculation is 1. But why? Actually it should be 0, shouldn't it?
I've tried it with the pow-function of the math-library but there the result also is 1:
int result;
result = std::pow(0 * 2, 1);
std::cout << result << std::endl;
In C++, and many other computer programming languages, ^ means XOR not power-of. So it may not have the precedence you expected from mathematics.
Use std::pow for exponents:
const int result = std::pow(0 * 2, 1);
std::cout << result << '\n';

C++ pass by reference not changing value

Below is the first part of a function meant to analyze a Tic-Tac-Toe board.
The aboutToWin() function returns true if a player is "about to win," ie has two in a row. The board is represented such that if player 1 has made a move in that square, the value in the 3x3 matrix will be 1. Player 2 will be -1. If no one has made a move, it will be 0.
The part that I put in this question is the first part, which checks the negative diagonal (ie positions 1, 5, and 9 on the board).
bool aboutToWin(int squares[3][3], int& position, bool p1)
{
// The value you are looking for is 2 for p1 and -2 for p2
int check = 2;
if (!p1)
{
check = -2;
}
// Check negative diagonal
int sum = 0;
// Go through negative diagonal
for (int i = 0; i < 3; i++)
{
sum += squares[i][i];
// Saves the position of the last checked 0 square
// If check passes, this will be the winning square
// If not, it will get handled and overwritten
if (squares[i][i] == 0)
{
// Calculates position from i
position = 1 + (4 * i);
std::cout << "\nPosition: " << position << "\n";
}
}
// If this diagonal added to check, stop the function and return now
if (sum == check)
return true;
...
}
This is the code that I'm running from the main() function to test this functionality:
int p;
std::cout << p;
int a3[3][3] = {{1, 0, 1},
{0, 0, 0},
{0, 0, 1}};
std::cout << "\nShould be 1, 5: " << aboutToWin(a3, p, true) << ", " << p;
The output is the following:
0
Position: 5
Should be true, 5: 1, 0
Why is this? I can see that the value gets changed during the function, but it doesn't transfer out of the function.
The problem with using:
std::cout << "\nShould be 1, 5: " << aboutToWin(a3, p, true) << ", " << p;
is that the order of the evaluation of the arguments is not defined unless you use C++17.
It looks like p is evaluated first in your setup before the call to aboutToWin.
Separate the calls.
auto ret = aboutToWin(a3, p, true);
std::cout << "\nShould be 1, 5: " << ret << ", " << p;

How to align numbers after decimal in C++ output [duplicate]

This question already has answers here:
Print leading zeros with C++ output operator?
(6 answers)
Closed 2 years ago.
I want cout to output an int with leading zeros, so the value 1 would be printed as 001 and the value 25 printed as 025. How can I do this?
With the following,
#include <iomanip>
#include <iostream>
int main()
{
std::cout << std::setfill('0') << std::setw(5) << 25;
}
the output will be
00025
setfill is set to the space character (' ') by default. setw sets the width of the field to be printed, and that's it.
If you are interested in knowing how the to format output streams in general, I wrote an answer for another question, hope it is useful:
Formatting C++ Console Output.
Another way to achieve this is using old printf() function of C language
You can use this like
int dd = 1, mm = 9, yy = 1;
printf("%02d - %02d - %04d", mm, dd, yy);
This will print 09 - 01 - 0001 on the console.
You can also use another function sprintf() to write formatted output to a string like below:
int dd = 1, mm = 9, yy = 1;
char s[25];
sprintf(s, "%02d - %02d - %04d", mm, dd, yy);
cout << s;
Don't forget to include stdio.h header file in your program for both of these functions
Thing to be noted:
You can fill blank space either by 0 or by another char (not number).
If you do write something like %24d format specifier than this will not fill 2 in blank spaces. This will set pad to 24 and will fill blank spaces.
cout.fill('*');
cout << -12345 << endl; // print default value with no field width
cout << setw(10) << -12345 << endl; // print default with field width
cout << setw(10) << left << -12345 << endl; // print left justified
cout << setw(10) << right << -12345 << endl; // print right justified
cout << setw(10) << internal << -12345 << endl; // print internally justified
This produces the output:
-12345
****-12345
-12345****
****-12345
-****12345
In C++20 you'll be able to do:
std::cout << std::format("{:03}", 25); // prints 025
In the meantime you can use the {fmt} library, std::format is based on.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
cout.fill( '0' );
cout.width( 3 );
cout << value;
Another example to output date and time using zero as a fill character on instances of single digit values: 2017-06-04 18:13:02
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
time_t t = time(0); // Get time now
struct tm * now = localtime(&t);
cout.fill('0');
cout << (now->tm_year + 1900) << '-'
<< setw(2) << (now->tm_mon + 1) << '-'
<< setw(2) << now->tm_mday << ' '
<< setw(2) << now->tm_hour << ':'
<< setw(2) << now->tm_min << ':'
<< setw(2) << now->tm_sec
<< endl;
return 0;
}
I would use the following function. I don't like sprintf; it doesn't do what I want!!
#define hexchar(x) ((((x)&0x0F)>9)?((x)+'A'-10):((x)+'0'))
typedef signed long long Int64;
// Special printf for numbers only
// See formatting information below.
//
// Print the number "n" in the given "base"
// using exactly "numDigits".
// Print +/- if signed flag "isSigned" is TRUE.
// Use the character specified in "padchar" to pad extra characters.
//
// Examples:
// sprintfNum(pszBuffer, 6, 10, 6, TRUE, ' ', 1234); --> " +1234"
// sprintfNum(pszBuffer, 6, 10, 6, FALSE, '0', 1234); --> "001234"
// sprintfNum(pszBuffer, 6, 16, 6, FALSE, '.', 0x5AA5); --> "..5AA5"
void sprintfNum(char *pszBuffer, int size, char base, char numDigits, char isSigned, char padchar, Int64 n)
{
char *ptr = pszBuffer;
if (!pszBuffer)
{
return;
}
char *p, buf[32];
unsigned long long x;
unsigned char count;
// Prepare negative number
if (isSigned && (n < 0))
{
x = -n;
}
else
{
x = n;
}
// Set up small string buffer
count = (numDigits-1) - (isSigned?1:0);
p = buf + sizeof (buf);
*--p = '\0';
// Force calculation of first digit
// (to prevent zero from not printing at all!!!)
*--p = (char)hexchar(x%base);
x = x / base;
// Calculate remaining digits
while(count--)
{
if(x != 0)
{
// Calculate next digit
*--p = (char)hexchar(x%base);
x /= base;
}
else
{
// No more digits left, pad out to desired length
*--p = padchar;
}
}
// Apply signed notation if requested
if (isSigned)
{
if (n < 0)
{
*--p = '-';
}
else if (n > 0)
{
*--p = '+';
}
else
{
*--p = ' ';
}
}
// Print the string right-justified
count = numDigits;
while (count--)
{
*ptr++ = *p++;
}
return;
}