So, i've made a program which is able to sort arrays, and i'm trying to sort an array containing double FP's, including 2-3 random ones i enter, pos inf, neg inf and a single NaN. so for this purpose i wish to sort the NaN.
So my code works, however when trying to sort the NaN, i'm unable to do so. What i'd like to do is sort it to the end, or have it put at the end of the sorted array. Is there anyway I can actually do this? Thanks in advance!!! code is as follows:
int main()
{
int start_s = clock();
int n, k = 4, j; // k is number of elements
double x = -0.0;
double i = 0;
double swap = 0;//used in the function as a place holder and used for swapping between other variables
double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN
//(1 / i) * 0
for (n = 0; n < (k - 1); n++) // for loop consists of variables and statements in order to arrange contents of array
{
for (j = 0; j < k - n - 1; j++)
{
if (a[j] > a[j + 1])
{
swap = a[j];
a[j] = a[j + 1];
a[j + 1] = swap;
}
}
}
cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
for (int i = 0; i < k; i++)// Loop up to number of elements within the array
{
cout << a[i] << " ";/* Output contents of array */
}
cout << endl; //new line
int stop_s = clock();
cout << "The execution time of this sort, is equal to: " << (stop_s - start_s) / double(CLOCKS_PER_SEC) * 1000 << " milliseconds" << endl;
return 0;
Since you're in C++ land anyway, why not use it to the full. First, indeed, move the NaN's and then sort. I've taken out 'noise' from your code and produced this, it compiles and runs (edit: on gcc-4.4.3). The main difference is that the NaN's are at the beginning but they're easily skipped since you will get a pointer to the start of non-NaN's.
#include <iostream>
#include <algorithm>
#include <math.h>
int main()
{
int n, k = 4, j; // k is number of elements
double x = -0.0;
double i = 0;
double a[100] = { (1/x) + (1/i), 2.3, 1/x *0, 1/i };//array of double elements // 1/i * 0 is NaN]
double *ptr; // will point at first non-NaN double
// divide the list into two parts: NaN's and non-NaN's
ptr = std::partition(a, a+k, isnan);
// and sort 'm
// EDIT: of course, start sorting _after_ the NaNs ...
std::sort(ptr, a+k);
cout << "The list of sorted elements within the array, is: " << endl; /* Output message to user */
for (int i = 0; i < k; i++)// Loop up to number of elements within the array
{
cout << a[i] << " ";/* Output contents of array */
}
cout << endl; //new line
return 0;
}
Do a linear scan, find the NaNs, and move them to the end - by swapping.
Then sort the rest.
You can also fix your comparator, and check for NaN there.
For the actual check see: Checking if a double (or float) is NaN in C++
you can use isnan() in cmath to check for NaNs. So, you can just change your comparison line from:
if (a[j] > a[j + 1])
to:
if (!std::isnan(a[j + 1]) && std::isnan(a[j]) || (a[j] > a[j + 1]))
just a reminder, you need to have:
#include <cmath>
at the top of your code.
Related
So im working on a class assignment where I need to take a base 2 binary number and convert it to its base 10 equivalent. I wanted to store the binary as a string, then scan the string and skip the 0s, and at 1s add 2^i. Im not able to compare the string at index i to '0, and im not sure why if(binaryNumber.at(i) == '0') isnt working. It results in an "out of range memory error". Can someone help me understand why this doesnt work?
#include <iostream>
using namespace std;
void main() {
string binaryNumber;
int adder;
int total = 0;
cout << "Enter a binary number to convert to decimal \n";
cin >> binaryNumber;
reverse(binaryNumber.begin(),binaryNumber.end());
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') { //THIS IS THE PROBLEM
//do nothing and skip to next number
}
else {
adder = pow(2, i);
total = adder + total;
}
}
cout << "The binary number " << binaryNumber << " is " << total << " in decimal form.\n";
system("pause");
}
Array indices for C++ and many other languages use zero based index. That means for array of size 5, index ranges from 0 to 4. In your code your are iterating from 1 to array_length. Use:
for (int i = 0; i < binaryNumber.length(); i++)
The problem is not with the if statement but with your loop condition and index.
You have your index begin at one, while the first character of a string will be at index zero. Your out memory range error is caused by the fact that the loop stops when less than or equal, causing the index to increase one too many and leave the memory range of the string.
Simply changing the loop from
for (int i = 1; i <= binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
To
for (int i = 0; i < binaryNumber.length(); i++) {
if(binaryNumber.at(i) == '0') {
}
else {
adder = pow(2, i);
total = adder + total;
}
}
Will solve the issue.
Because your started from 1 and not 0
for (int i = 1; i <= binaryNumber.length(); i++)
Try with that
for (int i = 0; i < binaryNumber.length(); i++)
I have to write a program that outputs Pascal's triangle for a computer science class, and everything is correct on the output until it gets past row 14, wherein it starts outputting odd irrational numbers. Here's my code
#include <iostream>
#include "myFunctions.h"
using namespace std;
int main() {
int rows;
cout << "Please Enter The Number of Rows: ";
cin >> rows;
cout << rows << endl;
for (int i = 0; i < rows; i++) {
for (int j = 1; j < (rows - i + 1); j++) {
cout << " ";
}
for (int k = 0; k <= i; k++) {
if (k == 0) {
cout << "1" << " ";
} else {
cout << combination(i, k) << " ";
}
}
cout << "\n";
}
return 0;
}
And here's my functions file:
#ifndef MYFUNCTIONS_CPP_INCLUDED
#define MYFUNCTIONS_CPP_INCLUDED
#include "myFunctions.h"
double factorial (int n) {
assert(n >= 0);
int v = 1;
while (n > 0) {
v *= n;
n--;
}
return v;
}
double combination (int a, int b) {
return (factorial(a) / (factorial(a - b) * factorial(b)));
}
#endif // MYFUNCTIONS_CPP_INCLUDED
And, finally, here's my header file.
#ifndef MYFUNCTIONS_H_INCLUDED
#define MYFUNCTIONS_H_INCLUDED
#include <iostream>
#include <cassert>
//*******************************************************
// description: finds factorial of value *
// return: double *
// precondition: that the value is valid and an integer *
// postcondition: returns the factorial of value *
//*******************************************************
double factorial( int n );
//********************************************************
// description: finds combination of value *
// return: double *
// precondition: both values are integers and valid *
// postcondition: returns the combination of two values *
//********************************************************
double combination( int a, int b );
#endif // MYFUNCTIONS_H_INCLUDED
I'm assuming that I did the equations within functions incorrect, or something specific is happening in main once it hits 14. Any help is appreciated.
What's going on
ints in C++ have a maximum size. As mentioned in comments, depends on your platform but for the sake of this question, I'll assume it's 2^31-1 which corresponds to a 32-bit signed integer and is what I most commonly see.
The issue comes in when you get to factorials. They grow very quickly. 14!=87178291200 which is a whole lot bigger than the maximum size of a 32 bit int. There's no feasible way to keep the whole factorial in memory for an arbitrary n! because of how large they can get.
It's not that your code is broken, it's simply running up against the physical bounds of computing.
How can we fix it?
First off, you could cancel out factorials. Basically, since we can guarantee that a>=b, we know that a!/b! is just multiplying the numbers between a and b. We can do that with a loop. Then it's just a matter of dividing by (a-b)!, which we already know how to do. This would look like
int combination(int a, int b)
{
int tmp = 1;
for(int ii = b;ii<=a;ii++)
tmp*=ii;
tmp /= factorial(b);
return tmp;
}
More efficiently, we can switch to a different algorithm. Wikipedia recommends using an iterative method for pascal's triangle. That is, each element can be calculated from two elements in the row above it. As #Damien mentions in comments, if you're looking for the kth element in row n, then you can calculate that by
int Combination(int n,int k)
{
if (k == 0 or k>n or n <= 1)
return 1;
return Combination(n-1,k) + Combination(n-1,k-1);
}
I am playing with the travelling salesman problem and am looking at the version where:
the towns are points in 2d space and there are paths from every town to all others and the lengths are the distances between the points. So it's very easy to implement the naive solution where you check all permutations of n points and calculate the length of the path.
I've found however that for n >= 10 the compiler does some magic and prints a value that is certainly not the actual shortest path. I compile with the Microsoft visual studio compiler in release mode with the default settings. For values (10,30) it thinks for 30 seconds and then returns some number that seems like it could be correct but it is not (I check in different ways). And for n > 40 it calculates a result immediately and is always 2.14748e+09.
I am looking for an explanation to what does the compiler do in the different situations (the (10,30) case is really interesting). And an example where these optimizations are more useful than the program just spinning to the end of the world.
vector<pair<int,int>> points;
void min_len()
{
// n is a global variable with the number of points(towns)
double min = INT_MAX;
// there are n! permutations of n elements
for (auto j = 0; j < factorial(n); ++j)
{
double sum = 0;
for (auto i = 0; i < n - 1; ++i)
{
sum += distance_points(points[i], points[i + 1]);
}
if (sum < min)
{
min = sum;
s_path = points;
}
next_permutation(points.begin(), points.end());
}
for (auto i = 0; i < n; ++i)
{
cout << s_path[i].first << " " << s_path[i].second << endl;
}
cout << min << endl;
}
unsigned int factorial(unsigned int n)
{
int res = 1, i;
for (i = 2; i <= n; i++)
res *= i;
return res;
}
Your factorial function is overflowing. Try replacing it with one returning int64_t and see your code taking 3 years to terminate for n > 20.
constexpr uint64_t factorial(unsigned int n) {
return n ? n * factorial(n-1) : 1;
}
Also, you don't need to calculate this at all. The std::next_permutation function returns 0 when all permutations have occured (starting from sorted position).
I am implementing a simple greedy merging algorithm that merges the two points which are closest to each other and averages their position. After merging two points at indices i and j, I need to replace one of them, say i, by the mean of the two points. Then, copy the last point in the array over the other point, say j, after which I can reduce the array size by 1 with all remaining points being within the new reduced range.
I need to repeat the above step until there are only 3 representative points left, each of which represents a group of merged points. I have written the following code, but I guess it is not able to update the array (pts). I would appreciate if anyone could help me figure out the mistake. Thanks in advance. This is my code:-
void merge_point(Point pts[], int &size) {
double a;
int x, y;
Point d;
while(size != 3) {
double min = get_distance(pts[0],pts[1]);
for (int i = 0; i < size; i++) {
for (int j = i+1; j < size; j++) {
get_distance(pts[i], pts[j]);
if ((a = get_distance(pts[i],pts[j])) <= min) {
x = i;
y = j;
}
a = get_distance(pts[i],pts[j]);
}
}
d = mean_point(pts[x],pts[y]);
pts[x] = d;
pts[y] = pts[size-1];
size = size - 1;
}
}
When I am entering the input array as :-
3 8 2
5.7 7.2 2.2
10.83 6.48 2.42
20.577 5.832 2.662
39.0963 5.2488 2.9282
74.283 4.72392 3.22102
141.138 4.25153 3.54312
268.162 3.82638 3.89743
509.507 3.44374 4.28718
968.063 3.09936 4.7159
My expected output should be:-
181.974 4.29686 3.57395
968.063 3.09936 4.7159
509.507 3.44374 4.28718
But, I am getting an output of:-
4.35 7.6 2.1
968.063 3.09936 4.7159
36.6506 5.8958 2.68145
Think I find out the problem, you don't update the min distance as soon as you find a new one during the cicle, try this:
cout << "distance between p[" << i << "] and " << "p[" << j << "]" << "is " << get_distance(pts[i], pts[j]) << '\n';
if ((a = get_distance(pts[i], pts[j])) <= min)
{
cout << "current min distance is between point[" << i << "]" << " and point[" << j << "]" << '\n';
min = a;
x = i;
y = j;
}
you've got to add this instruction:
min = a;
in order to update the min.
Otherwise it will works only for some edge cases.
I'm new to C++ and is trying to solve the beginner's problem of finding all prime numbers between 0 - nth number. I saw this code online and it works perfectly.
However, my question is what is the use of '+ 1' within the statement 'bool prime[n + 1];'? I have deleted it from the code and everything seems to work just fine. Is it necessary or is it redundant?
void SieveOfEratosthenes(int n) {
bool prime[n + 1];
memset(prime, true, sizeof (prime));
for (int p = 2; p * p <= n; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
// Print all prime numbers
for (int p = 2; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
int n = 1000;
cout << "Following are the prime numbers smaller "
<< " than or equal to " << n << endl;
SieveOfEratosthenes(n);
return 0;
}
In C++ an array of size N have index start from 0 to N-1. so for your problem, for N index assign N+1 size array. so that define the primality to N number.
In C++ (and many other languages) an array of size n has an index for 0 to (n - 1). In this case, you will need to check each number, up to and including n. You therefore need a spot in the array for n, at index prime[n]. This index will only exist if you oversize the array by 1. Otherwise, the array will stop at prime[n - 1].
The reason this works even if you take out the - 1 is that C++ is not fussy about array bounds - once you have an array you can legally read or write at any index, whether or not that index is safe. Notice I said legally, not safely - this is potentially very dangerous behaviour.