I've got a function that accepts a dynamic multidimensional array (which is initialized to 0) as a parameter, and I'm trying to modify certain values within the array in my function.
The function that accepts the array as a parameter is supposed to simulate the roll of two dice and output the frequency distribution to the array I made that's initialized to zero.
The code for it is as follows:
#include <iostream>
#include <cstdlib>
using namespace std;
int** rollDie(int numRolls, unsigned short seed, int** &rollarray)
{
srand(seed);
int side1, side2;
while (numRolls > 0)
{
side1 = 1 + rand() % 6;
side2 = 1 + rand() % 6;
rollarray[side1][side2]++;
numRolls--;
}
return rollarray;
}
int** initializeArray(void)
{
int i, j;
int** m = new int*[6];
for (i = 0; i < 6; i++)
m[i] = new int[6];
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
m[i][j] = 0;
return m;
}
int main()
{
int numRolls;
unsigned short seed;
int ** a = initializeArray();
cout << "rolls?\n";
cin >> numRolls;
cout << "seed?\n";
cin >> seed;
int ** b = rollDie(numRolls, seed, a);
int i,j;
for (i = 0; i < 6; i++) {
for (j = 0; j < 6; j++) {
cout << b[i][j];
}
cout << "\n";
}
}
Code works for me with just a few issues (I had to guess how you defined a. Next time add that too):
In the printing you should print a space after every number (minor)
In the random, you choose index as 1+rand()%6, so from 1 to 6, but when you print you take indexes from 0 to 5! So your first row and first column will be 0.
Other than that it seems to work.
Only when one goes and does something else does the answer come to mind. I suspect you declared a as:
int a[6][6];
which is an array of 36 integers. In your function, though, you're declaring rollarray to be a pointer to an array of pointers to integers. All you need to do is change the function signature to:
int* rollDie(int numRolls, unsigned short seed, int* rollarray)
As cluracan said, you also want to use array indices in the range 0 to 5.
This is a good case for either the judicious use of print statements or stepping through with a debugger to see what's really going on.
Related
So, here is my homework problem. It states "Enter five numbers five times. Every time, the program chooses the biggest number you enter, and it returns the arithmetic mean of those five largest numbers." Now, what I've done is use max function, however, I learned that it isn't useable in this way. Here is what I've tried:
#include <iostream>
using namespace std;
int main() {
int zbir = 0;
for (int i = 1; i < 6; i++) {
int a, b, c, d, e;
for (int j = 1; j < 6; j++) {
cin >> a >> b >> c >> d >> e;
}
int maks = max(a, b, c, d, e);
zbir = zbir + maks;
}
cout << zbir / 5;
}
There are two versions of max: the two-argument version, and the initializer list version. In this case, you have five arguments, so use the initializer list version:
std::max({a, b, c, d, e})
(You need to #include <algorithm> to use std::max.)
Within your code you do not need to have an inner for-loop because you are already collecting all 5 of the user numbers with the cin >> a >> b >> c >> d >> e; statement. Having a second for loop around it will cause you to collect 5 numbers from the user 25 times total.
This is an example of the alternative to using the max function in which case a single number is collected 5 times making use of an inner for-loop:
int main()
{
int sumOfMaxNums = 0;
int userNum = 0;
int maxNum = 0;
// it is a good practice to have a const that will bound the loop
// this way you can change it from here
// in other cases you can have two different const bounds, one for the inner loop and
// one for the outer loop because they may differ
const int NUM_ITERS = 5;
// This will handle asking the user to enter the numbers 5 times
for(int i = 0; i < NUM_ITERS; ++i)
{
// this loop will asks the user to enter a number 5 times and keep track of the max
for(int j = 0; j < NUM_ITERS; ++j)
{
cin >> userNum;
// here we want to set the maxNum to be the very first number that the user enters
// or we could set it to smallest negative number
if(j == 0)
{
maxNum = userNum;
}
else if(userNum > maxNum)
{
maxNum = userNum;
}
} // end of inner for-loop
sumOfMaxNums += maxNum;
} // end of outer for-loop
cout << sumOfMaxNums / static_cast<float>(NUM_ITERS) << "\n";
} // end of main
You probably want to calculate the mean as a float rather than an int, otherwise the program will round the final answer down to the nearest whole number. Also, you really don't need to use five variables to store each cycle's inputs, since you can ignore any inputs that are less than the running maximum for that cycle. This means you don't need to use std::max at all.
#include<iostream>
int main()
{
float running_total = 0;
for (int cycle = 1; cycle < 6; ++cycle)
{
float cycle_max;
for (int entry = 1; entry < 6; ++entry)
{
float input = 0;
std::cin >> input;
if (entry == 1 || input > cycle_max) cycle_max = input;
}
running_total += cycle_max;
}
std::cout << running_total / 5 << std::endl;
}
I need to fill in the blanks on pieces of code I've already been given. The problem is this:
The following class (long_number) represents a number of any length from 1 to 60. The default constructor generates the number 0. Need a print function, which prints the long_number. A constructor that turns an array of chars into a long_number.
I've gotten a few of the pieces started. Still trying to work out some of the later stuff. A lot of it is not quite making sense.
The places I put in code are:
the 1 in the statement int number [];
long_number::long_number in the no-arg constructor
1 in size =
the 0 and ++ in the first for loop in the constructor
the i in the number[i] = 0; statement
char and the ::long_number for the parameter in the 2nd constructor
_size in the statement size =
the greater than or equal to in the for statement
void long_number:: at the start of the print function
the -1 after max_digits and the i, in the for loop for (int i = max_digits - 1; i < max_digits; i++)
number and i in the cout statement
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class long_number {
private:
static const int max_digits = 60;
int number[1];
int size;
public:
long_number();
long_number(char a[], int _size);
void print();
};
long_number::long_number() {
size = 1;
for (int i = 0; i < max_digits; i++) {
number[i] = 0;
}
}
long_number::long_number(char input[], int _size) {
size = _size;
for (int i = 1; i <= size; i++) {
number[size -i] = (char) input[size - 1] - (int)'?';
}
void long_number::print() {
for (int i = max_digits - 1; i < max_digits; i++) {
cout << number[i];
}
cout << endl;
}
int main()
{
long_number n1;
n1.print();
cin.get();
return 0;
}
I question how I did the for loop in the print function and I need help with the constructor with parameters. The ? is one place I'm not sure what to put. There isn't anything similar in the problems I see in the textbook and he didn't show us any examples like this in class.
The ? is '0',the char array save the char '0' to '9'.And the function is save int to int number[].So need a change.
And others which need change is:
number[] define
int number[max_digits];
the print function, i++ change to i--
I want to output my histogram using the fewest amount of for loops possible
int* histogram(int size, int* arr)
{
int bin[10] = {};
for (int i = 0; i < size; i++)
{
if (arr[i] >= 0 && arr[i] < 10)
{
bin[0]++;
}
else if (arr[i] >= 10 && arr[i] < 20)
{
bin[1]++;
}
return bin;
}
Currently I am outputting the histogram like this:
cout << "0|";
for (int j = 0; j < bin[0]; j++)
cout << "*";
cout << endl;
But this is long and annoying. Is there a way to achieve the same output in fewer
for loops?
I am going to ignore the bugs in your histogram code, as it isn't really relevant to the question of optimising histogram output.
For information on the bug (returning a local variable), check out this Stack Overflow question.
Also, you are missing a curly brace. Always check that your code compiles and runs in its most minimalist form before posting it.
You state that the problem is that the method you use is "long and annoying", but it isn't clear if you are referring to the design of your code or the speed at which it performs.
Performance
The fastest you can possibly read the histogram is with O(n), where n is the number of bins in the histogram. In this sense your code is about as fast as it can get without micro-optimising it.
If you include the printing out of your histogram, then you have O(n*m), where m is the average number of entries per bin.
Writing a histogram is also O(n*k), where k is the number of entries in your array, because you have to figure out which bin each value belongs in.
Design
If the problem you have is that the code is bloated and unwieldy, then use less magic numbers and add more arguments to the function, like this:
#include <iostream>
void histogram(int const size, int const * const arr, unsigned int const number_of_bins, float const bin_min, float const bin_max, int * output)
{
float const binsize = (bin_max - bin_min)/number_of_bins;
for (int i = 0; i < size; i++)
{
for(int j = 0; j < number_of_bins; ++j)
{
if (arr[i] >= bin_min + binsize*j && arr[i] < bin_min + binsize*(j+1))
{
output[j]++;
}
}
}
}
int main(){
int const number_of_bins = 10;
float const bin_min = 0;
float const bin_max = 100;
int const size = 20;
int const array[size] = {5,6,20,40,44,50,110,6,-1,51,55,56,20,50,60,80,81,0,32,3};
int bin[number_of_bins] = {};
histogram(size, array, number_of_bins, bin_min, bin_max, bin);
for(int i = 0; i < number_of_bins; ++i)
{
std::cout << i << "|";
for (int j = 0; j < bin[i]; j++)
{
std::cout << "*";
}
std::cout << std::endl;
}
}
Compiled with:
g++ main.cc -o Output
Output:
0|*****
1|
2|**
3|*
4|**
5|*****
6|*
7|
8|**
9|
(Bonus, your bugs are fixed)
First of all your program is incorrect since, as pointed out, you return a pointer to a local variable form a function. To correct this you should use either std::array<Type, Size> or std::vector<Type>.
Regarding your question if you want short and compact code try this:
#include <string>
#include <algorithm>
#include <iostream>
#include <array>
std::array<int, 10> bin;
// Fill your array here
int i = 0;
std::for_each(bin.begin(), bin.end(), [&i](auto x)
{
std::cout << i++ << "|" << std::string(x, '*') << std::endl;
});
This code takes advantage of fill constructor of std::string which avoids your for cycle. But since you want to iterate through the array you need to do it in one way or the other. Either by an explicit for or by calling another function.
Note: this code is less efficient than a standard for loop but your question is how to avoid these.
The Sieve of Eratosthenes and Goldbach's Conjecture
Implement the Sieve of Eratosthenes and use it to find all prime
numbers less than or equal to one million. Use the result to
prove Goldbach's Conjecture for all even integers between four and
one million, inclusive.
Implement a function with the following declaration:
void sieve(int array[], int num);
This function takes an integer array as its argument. The array
should be initialized to the values 1 through 1000000. The
function modifies the array so that only the prime numbers remain;
all other values are zeroed out.
This function must be written to accept an integer array of any
size. You must should output for all primes numbers between 1 and
1000000, but when I test your function it may be on an array of a
different size.
Implement a function with the following declaration:
void goldbach(int array[], int num);
This function takes the same argument as the previous function
and displays each even integer between 4 and 1000000 with two
prime numbers that add to it.
The goal here is to provide an efficient implementation. This
means no multiplication, division, or modulus when determining if
a number is prime. It also means that the second function must find
two primes efficiently.
Output for your program: All prime numbers between 1 and 1000000
and all even numbers between 4 and 1000000 and the two prime
numbers that sum up to it.
DO NOT provide output or a session record for this project!
This is the code that I have so far, my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this, thank you!
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
void sieve(int array[], int num);
void goldbach(int array[], int num);
const int arraySize = 1000000;
int nums[arraySize];
int main(){
for (int i = 0; i <= arraySize; ++i)
nums[i] = 1;
nums[0] = nums[1] = 0;
sieve(nums, arraySize);
for(int i = 0; i < 10000; ++i){
if (nums[i] > 0){
cout << nums[i] << " ";
}
}
goldbach(nums, arraySize);
return 0;
}
void sieve(int array[], int num) {
int squareR = (int)sqrt(num);
for(int i = 2; i <= squareR; ++i){
int k;
if(array[i]){
for(k = i*i; k <= num; k += i)
array[k] = 0;
}
if (array[i] == 1){
array[i] = i;
}
}
}
void goldbach(int array[], int num){
int i, r = 0;
for (i = 4; i <= num; i += 2){
for (int j = 2; j <= i/2; j++)
if (array[j] && array[i-j]) r ++;
}
}
my problem is that it displays numbers higher than 1,000 as 1s, how can I go about this
That's because you're not updating the values in the array above 1000, here:
for(int i = 2; i <= squareR; ++i){
...
if (array[i] == 1){
array[i] = i;
clearly the array's entries above squareR are not updated and remain at the value you initialized them, which is 1.
However I you don't need this update at all. You can drop it and simplify your code, keeping the array's entries as either 1 (for primes) or 0 (for non-primes). with this, and display your result like this (in main):
for(int i = 0; i < arraySize; ++i){
if (nums[i] != 0){
// cout << nums[i] << " "; // <-- drop this
cout << i << " "; // <-- use this
}
}
I am very very new to C++ and I am trying to call the function "jacobi" which performs a user specified number of iterations for the jacobi method (or at least I hope so). On the line where I call 'jacobi' I get the error "No matching function to call to "jacobi". I have read other posts similar to this one and have tried to apply it to my own code but I have been unsuccessful. Maybe there are other issues in my code causing this problem. As mentioned I am very new C++ so any help would be appreciated and please break it down for me.
#include <iostream>
using namespace std;
void jacobi (int size, int max, int B[size], int A[size][size], int init[size], int x[size]){
////
//// JACOBI
////
int i,j,k,sum[size];
k = 1;
while (k <= max) // Only continue to max number of iterations
{
for (i = 0; i < size; i++)
{
sum[i] = B[i];
for (j = 0; j < size; j++)
{
if (i != j)
{
sum[i] = sum[i] - A[i][j] * init[j]; // summation
}
}
}
for (i = 0; i < size; i++) ////HERE LIES THE DIFFERENCE BETWEEN Guass-Seidel and Jacobi
{
x[i] = sum[i]/A[i][i]; // divide summation by a[i][i]
init[i] = x[i]; //use new_x(k+1) as init_x(k) for next iteration
}
k++;
}
cout << "Jacobi Approximation to "<<k-1<<" iterations is: \n";
for(i=0;i<size;i++)
{
cout <<x[i]<< "\n"; // print found approximation.
}
cout << "\n";
return;
}
int main (){
// User INPUT
// n: number of equations and unknowns
int n;
cout << "Enter the number of equations: \n";
cin >> n;
// Nmax: max number of iterations
int Nmax;
cout << "Enter max number of interations: \n";
cin >> Nmax;
// int tol;
// cout << "Enter the tolerance level: " ;
// cin >> tol;
// b[n] and a[n][n]: array of coefficients of 'A' and array of int 'b'
int b[n];
int i,j;
cout << "Enter 'b' of Ax = b, separated by a space: \n";
for (i = 0; i < n; i++)
{
cin >> b[i];
}
// user enters coefficients and builds matrix
int a[n][n];
int init_x[n],new_x[n];
cout << "Enter matrix coefficients or 'A' of Ax = b, by row and separate by a space: \n";
for (i = 0; i < n; i++)
{
init_x[i] = 0;
new_x[i] = 0;
for (j = 0; j < n; j++)
{
cin >> a[i][j];
}
}
jacobi (n, Nmax, b, a, init_x, new_x);
}
The problem:
There are several problems, related to the use of arrays:
You can't pass arrays as parameter by value.
You can't pass multidimensional arrays as parameter if the dimensions are variable
You can't define arrays of variable length in C++
Of course there are ways to do all these kind of things, but it uses different principles (dynamic allocation, use of pointers) and requires additional work (especially for the access of multidimensional array elements).
Fortunately, there is a much easier solution also !
The solution:
For this kind of code you should go for vector : these manage variable length and can be passed by value.
For the jacobi() function, all you have to do is to change its definition:
void jacobi(int size, int max, vector<int> B, vector<vector<int>> A, vector<int> init, vector<int> x) {
int i, j, k;
vector<int> sum(size); // vector of 'size' empty elements
// The rest of the function will work unchanged
...
}
Attention however: the vectors can be of variable size and this jacobio implementation assumes that all the vectors are of the expected size. In professional level code you should check that it's the case.
For the implementation of main(), the code is almost unchanged. All you have to do is to replace array definitions by vector definitions:
...
vector<int> b(n); // creates a vector that is initialized with n elements.
...
vector<vector<int>> a(n,vector<int>(n)); // same idea for 2 dimensional vector (i.e. a vector of vectors)
vector<int> init_x(n), new_x(n); // same principle as for b
...