I'm currently working on a program that is pretty well explained in the comment section at the top. I know that when n = 10, E(4) = 8 and E(6) = 9. However, I'm showing E(4) = 7 and E(6) now tells me k is too large. I'm fairly new to coding, and I could really use some pointers on finding my mistakes (no pun intended).
Edit: I do realize that this program is pretty inefficient. If anyone has some tips on optimization they would be much appreciated as well.
Edit: Solved! I ended up making a 2D vector and made a function to sort it in ascending order. My issue with the primes vector not filling was due to me accidentally passing rads to the findPrimes function.
/* This program takes in integers n and k. It fills a vector with prime numbers up to n.
It then finds all prime numbers that can divide integers 1 to n with no remainder and
fills a vector with the results and the associated n (i in loop) value. The vector is
then sorted and the (k-1)th element (k for user) of the resulting vector is displayed. */
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void findPrimes(vector<int>&, int);
bool sortRads(const vector<int>& a, const vector<int>& b);
int main(int argc, const char * argv[]) {
vector<int> primes;
vector< vector<int> > kVec;
vector<int> rads (2, 0);
int n;
int k;
int radN;
cout << "Enter n: ";
cin >> n;
cout << "Enter k: ";
cin >> k;
findPrimes(primes, n);
//Fills rads vector with rad(n)
for (int i = 1; i <= n; i++) {
radN = 1;
for (int j = 0; ((j < primes.size()) && (j < i)); j++) {
if (i % primes[j] == 0) {
radN = radN * primes[j];
}
}
rads[0] = i;
rads[1] = radN;
kVec.push_back(rads);
}
sort(kVec.begin(), kVec.end(), sortRads);
//Ensures k is within the bounds of rads vector
while (k > n) {
cout << "k value too large. new k: ";
cin >> k;
}
cout << "E(" << k << "): " << kVec[k-1][0] << endl;
return 0;
}
void findPrimes(vector<int>& primes, int n) {
bool isPrime;
primes.push_back(1);
primes.push_back(2);
for (int i = 3; i <= n; i++) {
isPrime = true;
for (int j = 2; j <= (i/2); j++) {
if (i % j == 0) {
isPrime = false;
}
}
if (isPrime == true) {
primes.push_back(i);
}
}
}
bool sortRads(const vector<int>& a, const vector<int>& b) {
if (a[1] == b[1]) {
return a[0] < b[0];
}
else {
return a[1] < b[1];
}
}
The only thing that can possibly be causing errors is when you use the k value. It's read in, but you never check if k is bigger than the size of the vector. If it is, then there will be problems because you're trying to access something outside the vector. If you change the program to handle that error where k is bigger than the size of the array, then you shouldn't get any memory errors or invalid reads.
-Ash
The incorrect results may be because at the end of main you're sorting primes and printing the kth prime rather than sorting rads and printing rad[k].
Related
Here in this question the function call is not executing also tell me abut can't I use array instead of vectors here.
if Possible to use array please provide me with code that how to pass arrays to a function in c++
Here in this question the function call is not executing also tell me abut can't I use array instead of vectors here.
if Possible to use array please provide me with code that how to pass arrays to a function in c++
#include <iostream>
#include <vector>
using namespace std;
int recursion(vector<vector<int>> &v, int n, int m)
{
if (n == 0 && m == 0)
{
return v[n][m];
}
int left = v[n][m] + recursion(v, n - 1, m);
int right = v[n][m] + recursion(v, n, m - 1);
return min(left, right);
}
int main()
{
int n, m;
cout << "enter the value of n and m" << endl;
cin >> n >> m;
cout << n << m;
//it's doing nothing after this point.
vector<vector<int>> vec(n, vector<int>(m));
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
vec[i][j] = (i)*m + (j + 1);
}
}
int result = recursion(vec, n, m);
cout << result;
return 0;
}
vec[i][j] = (i)*m + (j + 1);
is out-of-bounds for i = n and j = m. Same problem with calling recursion(vec, n, m);
I am writing a program that takes a user-inputted list of up to 25 integers, then prints the sorted list using bubble sorting, the sorted list in descending order, and some other info about the list like the median, minimum and maximum, and mode.
I have tested all of my functions within the program individually on an array I created using initializer lists (not from user input/cin) and they work fine, but when I run the program something is off. For example, when I input 1,2,3,4, the function that prints the sorted list in descending order prints 3,2,1, -858993460. It always leaves out the greatest integer and adds on -858993460 at the end no matter what values I put into the input array. Here's the relevant part of my code:
#include <iostream>
using namespace std;
void input(int ulist[26], int& n);
void Bubblesort(int ulist[26], int slist[26], int n);
void print(int list[26], int n);
int n;
void reversesort(int slist[26], int n);
void main()
{
int ulist[26], slist[26];
input(ulist, n);
cout << "Unsorted";
print(ulist, n);
cout << "Sorted";
Bubblesort(ulist, slist, n);
print(slist, n);
reversesort(slist, n);
cin >> n;
}
void input(int ulist[26], int& n)
{
int i(0), value;
cout << "enter value : \n";
cin >> value;
while (i < 25 && value != -999)
{
ulist[i] = value;
i++;
if (i < 25)
{
cin >> value;
}
}
n = i;
}
void Bubblesort(int ulist[26], int slist[26], int n)
{
int i, j, temp;
for (i = 0; i < n; i++)
slist[i] = ulist[i];
for (j = 25 - 1; j > 0; j--) //25 is Length of the array
for (i = 0; i < j; i++)
if (slist[i] > slist[i + 1])
{
temp = slist[i];
slist[i] = slist[i + 1];
slist[i + 1] = temp;
}
}
void print(int list[26], int n)
{
int i;
cout << " list of numbers are : \n";
for (i = 0; i < n; ++i)
{
cout << list[i] << '\n';
}
cout << "\n\n";
}
void reversesort(int slist[26], int n) //checked w online compiler, works
{
cout << "List of numbers in descending order is: \n";
for (int i = n - 1; i >= 0; --i)
cout << slist[i] << ", ";
cout << "\n";
}
I'm assuming this is some sort of memory problem and that the source of this has to do with passing slist, which was modified in the bubblesort function, through the functions I wrote. I'm pretty new to C++ (coming from python) so I'm assuming I'm missing something as far as passing arrays to functions is concerned.
EDIT: I guess to sum everything up - how can I take the data inputted in the input function and use that array in another function? And how can I take the array that has been sorted by the bubblesort function and use that array in another function?
The first instance of undefined behavior in your code is
if (slist[i] > slist[i + 1])
in Bubblesort.
Due to
for (j = 25 - 1; j > 0; j--)
for (i = 0; i < j; i++)
the maximum index accessed by this loop is slist[24] (24 from i + 1 where i < j and j = 25 - 1 = 24, so i = 23).
Your input is only 4 numbers, so only slist[0] through slist[3] are initialized. The remaining elements (slist[4] through slist[25]) are uninitialized. Reading from an uninitialized variable has undefined behavior.
I was making an algorithm to solve Problem 1310 from the URI Online Judge and at some point i needed to delete an item from an array in an easy way, so i declared a vector, but, besides having no issues running whatsoever, my code doesn´t print anything using , cout doesn´t work at all.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int Lucro(int c, int n, vector<int> r){
if (n == 0){
return 0;
}else if (n == 1){
return max(r[0] - c, 0);
}
int q;
q = 0;
for (int k = 0; k < n; k++){
r.erase(r.begin() + k);
q = max(q, r[k] - c + Lucro(c, n-1, r));
}
return q;
}
int main()
{
int C, N, items;
cin >> N >> C;
vector<int> R;
for (int i = 0; i < N; i++){
cin >> items;
R.push_back (items);
}
cout << Lucro(C, N, R) << endl;
cout << 'test' << endl;
}
As i´m quite new to using vectors in c++, could someone please explain to me what´s going on and how to fix it?
Most likely your program crashes because you are getting out-of-range of your vector by erasing elements and not decrementing the size n:
for (int k = 0; k < n; k++){
r.erase(r.begin() + k); //decrement n after this
q = max(q, r[k] - c + Lucro(c, n-1, r));
}
In any case you shouldn't really have n variable at all, you should use r.size() to always get the current size of the vector.
How can I solve this problem without getting time limit exceeded
http://codeforces.com/problemset/problem/474/B
I tried putting all ranges in a 2D vector then looking for the desired index using binary search but it seems that the loop in the fn BS() takes a lot to execute as the size of the vector can be 10^6.
here is my code:
#include <iostream>
#include <vector>
using namespace std;
int Search(vector <vector<int> > a,int key){
int start = 0;
int end = a.size() - 1;
while (start <= end){
int mid = start + (end - start) / 2;
if (a[mid][0] > key && a[mid][1] > key){
end = mid - 1;
}
else if (a[mid][0] < key && a[mid][1] < key){
start = mid + 1;
}
else {
return mid;
}
}
return -1;
}
vector <int> BS(vector <vector <int> > v, vector<int> keys){
int j = 0;
vector <int> piles;
for (int i = 0; i < keys.size(); i++){
piles.push_back(Search(v, keys[i])+1);
}
return piles;
}
vector < vector<int> > Range(vector<int> v){
vector < vector<int> > ranges(v.size());
int sum1 = 1;
int sum2 = v[0];
for (int i = 0; i < v.size(); i++){
if (i == 0){
ranges[i].push_back(sum1);
ranges[i].push_back(v[i]);
sum1 += v[i];
}
else{
ranges[i].push_back(sum1);
sum2 += v[i];
ranges[i].push_back(sum2);
sum1 += v[i];
}
}
return ranges;
}
int main(){
int n, m;
cin >> n;
vector <int> a, q;
vector < vector <int> > v;
for (int i = 0; i < n; i++){
int k;
cin >> k;
a.push_back(k);
}
cin >> m;
for (int i = 0; i < m; i++){
int l;
cin >> l;
q.push_back(l);
}
v = Range(a);
vector <int> jucy = BS(v, q);
for (int i = 0; i < jucy.size(); i++){
cout << jucy[i] << endl;
}
}
In fact i don`t think you need 2D vector at all, you need just 1D. Which for example would look like this [2,9,12,16,25], the upper bound of each pile, you can construct this really easy. Then for every juicy worm you do binary search in that manner that it returns index with value greater or equal to the value you are looking for. The index you got from the search is the pile you are looking for.
Some pseudo-code:
A[n] - vector of upper bounds
A[0] = a0
For each 0<i<=n A[i]=A[i-1]+ai
For each q do std lower_bound on A looking for q,
the index you get is with first value equal or greater than q, so the pile where is q.
and C++ code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
int n, m;
cin >> n;
vector<int>A;
A.resize(n);
int ai;
cin >> ai;
A[0]=ai;
for (int i = 1; i < n; i++){
cin >> ai;
A[i]=A[i-1]+ai;
}
cin >> m;
int q;
for (int i = 0; i < m; i++){
cin >> q;
cout << std::distance(A.begin(),std::lower_bound(A.begin(),A.end(),q))+1<<endl;
}
return 0;
}
You have to add +1 to distance because the piles are numbered from 1. Work for the example, and looks pretty fast.
The most obvious optimization opportunity is, instead of using a vector<vector<int>> use a vector<int> and manually adjust the 2D indices to 1D. You can write a simple wrapper class that does this for you.
The reason that that will be much faster is that then all the memory will be allocated as a single contiguous unit. If you have a vector of vectors, then each row will be somewhere else and you'll have lots of cache misses.
Here's a code example:
struct 2D_Vector {
std::vector<int> me_;
int ncols_;
2D_Vector(int nrows, int ncols) : me(nrows * ncols), ncols_(ncols) {}
int & get(int y, int x) { return me_[y * ncols_ + x]; }
const int & get(int y, int x) const { return me_[y * ncols_ + x]; }
...
};
If you preallocate this with all the space that it will need, then it should use memory very efficiently.
Also, passing large function parameters by value instead of by reference is very wasteful, because it results in needless copies being made and destroyed. (Like WhozCraig pointed out.)
I've looked up some websites but I couldn't find an answer to my problem.
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 6;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
printing(Array);
}
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{
int c, tmp, x;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into Array[][]
for (int e = 0; e<AS; e++)
{
for (int d = 0; d<AS; d++)
{
Brray[dice] = Array[e][d];
dice++;
}
}
***There's a part missing here***
}
What I have to do is, write a program using 3 functions.
The 1st function would fill my 2D array randomly (no problem with this part)
the 2nd function would print the unsorted array on the screen (no problem with this part)
and the 3rd function would sort my array diagonally as shown in this picture:
Then I need to call the 2nd function to print the sorted array. My problem is with the 3rd function I turned my 2D array into a 1D array and sorted it using Bubble sorting, but what I can't do is turn it back into a 2D array diagonaly sorted.
If you can convert from a 2D array to a 1D array, then converting back is the reverse process. Take the same loop and change around the assignment.
However in your case the conversion itself is wrong. It should take indexes in the order (0;0), (0;1), (1;0). But what it does is take indexes in the order (0;0), (0;1), (1;1).
My suggestion is to use the fact that the sum of the X and Y coordinates on each diagonal is the same and it goes from 0 to AS*2-2.
Then with another loop you can check for all possible valid x/y combinations. Something like this:
for ( int sum = 0; sum < AS*2-1; sum++ )
{
for ( int y = sum >= AS ? sum-AS+1 : 0; y < AS; y++ )
{
x = sum - y;
// Here assign either from Array to Brray or from Brray to Array
}
}
P.S. If you want to be really clever, I'm pretty sure that you can make a mathematical (non-iterative) function that converts from the index in Brray to an index-pair in Array, and vice-versa. Then you can apply the bubble-sort in place. But that's a bit more tricky than I'm willing to figure out right now. You might get extra credit for that though.
P.P.S. Realization next morning: you can use this approach to implement the bubble sort directly in the 2D array. No need for copying. Think of it this way: If you know a pair of (x;y) coordinates, you can easily figure out the next (x;y) coordinate on the list. So you can move forwards through the array from any point. That is all the the bubble sort needs anyway.
Suppose you have a 0-based 1-dimensional array A of n = m^2 elements. I'm going to tell you how to get an index into A, given and a pair of indices into a 2D array, according to your diagonalization method. I'll call i the (0-based) index in A, and x and y the (0-based) indices in the 2D array.
First, let's suppose we know x and y. All of the entries in the diagonal containing (x,y) have the same sum of their coordinates. Let sum = x + y. Before you got to the diagonal containing this entry, you iterated through sum earlier diagonals (check that this is right, due to zero-based indexing). The diagonal having sum k has a total of k + 1 entries. So, before getting to this diagonal, you iterated through 1 + 2 + ... + (sum - 1) entries. There is a formula for a sum of the form 1 + 2 + ... + N, namely N * (N + 1) / 2. So, before getting to this diagonal, you iterated through (sum - 1) * sum / 2 entries.
Now, before getting to the entry at (x,y), you went through a few entries in this very diagonal, didn't you? How many? Why, it's exactly y! You start at the top entry and go down one at a time. So, the entry at (x,y) is the ((sum - 1) * sum / 2 + y + 1)th entry, but the array is zero-based too, so we need to subtract one. So, we get the formula:
i = (sum - 1) * sum / 2 + y = (x + y - 1) * (x + y) / 2 + y
To go backward, we want to start with i, and figure out the (x,y) pair in the 2D array where the element A[i] goes. Because we are solving for two variables (x and y) starting with one (just i) and a constraint, it is trickier to write down a closed formula. In fact I'm not convinced that a closed form is possible, and certainly not without some floors, etc. I began trying to find one and gave up! Good luck!
It's probably correct and easier to just generate the (x,y) pairs iteratively as you increment i, keeping in mind that the sums of coordinate pairs are constant within one of your diagonals.
Store the "diagonally sorted" numbers into an array and use this to display your sorted array. For ease, assume 0-based indexing:
char order[] = { 0, 1, 3, 6, 10, 2, 4, 7, 11, 15, .. (etc)
Then loop over this array and display as
printf ("%d", Array[order[x]]);
Note that it is easier if your sorted Array is still one-dimensional at this step. You'd add the second dimension only when printing.
Following may help you:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
template<typename T>
class DiagArray
{
public:
DiagArray(int size) : width(size), data(size * size), orders(size * size)
{
buildTableOrder(size);
}
const T& operator() (int x, int y) const { return data[orders[width * y + x]]; }
T& operator() (int x, int y) { return data[orders[width * y + x]]; }
void sort() { std::sort(data.begin(), data.end()); }
void display() const {
int counter = 0;
for (auto index : orders) {
std::cout << std::setw(5) << data[index];
counter++;
if (counter % width == 0) {
std::cout << std::endl;
}
}
}
private:
void buildTableOrder(int size)
{
int diag = 0;
int x = 0;
int y = 0;
for (int i = 0; i != size * size; ++i) {
orders[y * size + x] = i;
++y;
--x;
if (x < 0 || y >= size) {
++diag;
x = std::min(diag, size - 1);
y = diag - x;
}
}
}
private:
int width;
std::vector<T> data;
std::vector<int> orders;
};
int main(int argc, char *argv[])
{
const int size = 5;
DiagArray<int> da(size);
for (int y = 0; y != size; ++y) {
for (int x = 0; x != size; ++x) {
da(x, y) = size * y + x;
}
}
da.display();
std::cout << std::endl;
da.sort();
da.display();
return 0;
}
Thank you for your assistance everyone, what you said was very useful to me. I actually was able to think about clearly and came up with a way to start filling the array based on your recommendation, but one problem now, Im pretty sure that my logic is 99% right but there's a flaw somewhere. After I run my code the 2nd array isnt printed on the screen. Any help with this?
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 5;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
}
printing(Array);
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{int n;
int real;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
int median;
int row=0;
int col=AS-1;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into sorted Array[][]
for(int e=4;e>=0;e--)//e is the index of the diagonal we're working in
{
if(AS%2==0)
{median=0.5*(Brray[AS*AS/2]+Brray[AS*AS/2-1]);
//We start filling at median - Brray[AS*AS/2-1]
while(row<5 && col>=0)
{real=median-Brray[AS*AS/2-1];
Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
else {
median=Brray[AS*AS/2];
//We start filling at Brray[AS*AS/2-AS/2]
while(row<5 && col>=0)
{real=Brray[AS*AS/2-AS/2];
n=Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
}
return n;
}
Thanks again for your assistance