I am trying to create a 3-Dimensional array which gets filled up with pseudo-random numbers ranging from 0 to 9 (inclusive). This is my first time working with arrays containing more than 2 dimensions, so I am a bit lost.
At first the only number being inputted into the array was a 1, but after changing some code around, every number but the last one is a 1, and the last digit is pseudo-random. To make matters worse with the new situation I am in, when I hit enter, I get a weird error message.
Besides these two errors (error filling up array, and debug error), I also cannot figure out how in the world to print it out in 3 groups of 3 x 3 numbers, although right now, that is a lower issue on my agenda (although hints for that would be appreciated).
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main(){
srand(time(NULL));
const int arrayRow = 3, arrayColumns = 3, arrayDepth = 3;
int fun[arrayRow][arrayColumns][arrayDepth];
for (int r = 0; r < 4; r++){
for (int c = 0; c < 4; c++){
for (int d = 0; d < 4; d++){
int value = rand() % 10;
fun[r][c][d] = value;
cout << fun[arrayRow][arrayColumns][arrayDepth];
}
}
}
cout << "Complete." << endl;
system("pause");
}
You declare a 3x3x3 array.
Then you proceed to initialize as if it was a 4x4x4 array. Here's a simplified explanation of where your code goes wrong:
int foo[3];
This declares a 3-element array. foo[0] through foo[2].
for (int bar=0; bar<4; ++bar)
{
foo[bar]=1;
}
This attempts to initialize foo[0] through foo[3]. Four elements. Three-element array.
Undefined behavior.
Your code makes the same error, but with a 3-dimensional array, in all three dimensions.
fun[arrayRow][arrayColumns][arrayDepth]
allocates an array that can be indexed with a range of 0 .. 2 on each axis.
for (int r = 0; r < 4; r++){
roams from 0 to 3 and overruns the array.
for (int r = 0; r < arrayRow; r++){
will solve that. You will have to do the same for the other for loops as well as they are all out of range.
In addition,
cout << fun[arrayRow][arrayColumns][arrayDepth];
resolves to
cout << fun[3][3][3];
and is out of range and always returns the same value.
Related
I have been doing this problem for 2 days now, and I still can't figure out how to do this properly.
In this program, I have to input the number of sticks available (let's say 5). Then, the user will be asked to input the lengths of each stick (space-separated integer). Let's say the lengths of each stick respectively are [4, 4, 3, 3, 4]. Now, I have to determine if there are pairs (2 sticks of same length). In this case, we have 2 (4,4 and 3,3). Since there are 2 pairs, we can create a canvas (a canvas has a total of 2 pairs of sticks as the frame). Now, I don't know exactly how to determine how many "pairs" there are in an array. I would like to ask for your help and guidance. Just note that I am a beginner. I might not understand complex processes. So, if there is a simple (or something that a beginner can understand) way to do it, it would be great. It's just that I don't want to put something in my code that I don't fully comprehend. Thank you!
Attached here is the link to the problem itself.
https://codeforces.com/problemset/problem/127/B
Here is my code (without the process that determines the number of pairs)
#include<iostream>
#include<cmath>
#define MAX 100
int lookForPairs(int numberOfSticks);
int main(void){
int numberOfSticks = 0, maxNumOfFrames = 0;
std::cin >> numberOfSticks;
maxNumOfFrames = lookForPairs(numberOfSticks);
std::cout << maxNumOfFrames << std::endl;
return 0;
}
int lookForPairs(int numberOfSticks){
int lengths[MAX], pairs = 0, count = 0, canvas = 0;
for(int i=0; i<numberOfSticks; i++){
std::cin >> lengths[i];
}
pairs = floor(count/2);
canvas = floor(pairs/2);
return count;
}
I tried doing it like this, but it was flawed. It wouldn't work when there were 3 or more integers of the same number (for ex. [4, 4, 3, 4, 2] or [5. 5. 5. 5. 6]). On the first array, the count would be 6 when it should only be 3 since there are only three 4s.
for(int i=0; i<numberOfSticks; i++){
for (int j=0; j<numberOfSticks; j++){
if (lengths[i] == lengths[j] && i!=j)
count++;
}
}
Instead of storing all the lengths and then comparing them, count how many there are of each length directly.
These values are known to be positive and at most 100, so you can use an int[100] array for this as well:
int counts[MAX] = {}; // Initialize array to all zeros.
for(int i = 0; i < numberOfSticks; i++) {
int length = 0;
std::cin >> length;
counts[length-1] += 1; // Adjust for zero-based indexing.
}
Then count them:
int pairs = 0;
for(int i = 0; i < MAX; i++) {
pairs += counts[i] / 2;
}
and then you have the answer:
return pairs;
Just an extension to molbdnilo's answer: You can even count all pairs in one single iteration:
for(int i = 0; i < numberOfSticks; ++i)
{
if(std::cin >> length) // catch invalid input!
{
pairs += flags[length] == 1; // add a pair if there is already a stick
flags[length] ^= 1; // toggle between 0 and 1...
}
else
{
// some appropriate error handling
}
}
Note that I skipped subtracting 1 from the length – which requires the array being one larger in length (but now it can be of smallest type available, i.e. char), while index 0 just serves as an unused sentinel. This variant would even allow to use bitmaps for storing the flags, though questionable if, with a maximum length that small, all this bit fiddling would be worth it…
You can count the number of occurrences using a map. It seems that you are not allowed to use a standard map. Since the size of a stick is limited to 100, according to the link you provided, you can use an array, m of 101 items (stick's minimum size is 1, maximum size is 100). The element index is the size of the stick. The element value is the number of sticks. That is, m[a[i]] is the number of sticks of size a[i]. Demo.
#define MAX 100
int n = 7;
int a[MAX] = { 1,2,3,4,1,2,3 };
int m[MAX + 1]; // maps stick len to number of sticks
void count()
{
for (int i = 0; i < n; ++i)
m[a[i]]++;
}
int main()
{
count();
for (int i = 1; i < MAX + 1; ++i)
if (m[i])
std::cout << i << "->" << m[i] << std::endl;
}
Your inner loop is counting forward from the very beginning each time, making you overcount the items in your array. Count forward from i , not zero.
for(int i=0; i<numberOfSticks; i++)
{
for (int j=i; j<numberOfSticks; j++) { // count forward from i (not zero)
if (lengths[i] == lengths[j] && i!=j)
{ // enclosing your blocks in curly braces , even if only one line, is easier to read
count++; // you'll want to store this value somewhere along with the 'length'. perhaps a map?
}
}
}
I was given the integers 15, 16, 17 ,18 ,19 and 20.
I am supposed to put only the numbers divisible by 4 into a vector and then display the values in the vector.
I know how to do the problem using arrays but I'm guessing I don't know how to properly use pushback or vectors.
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> arrmain; int i,j;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
}
}
return 0;
}
wanted output: Numbers divisible by 4: 16, 20
As already mentioned in the comments, you have a couple of problems in your code.
All which will bite you in the end when writing more code.
A lot of them can be told to you by compiler-tools. For example by using -Weverything in clang.
To pick out the most important ones:
source.cpp:8:10: warning: declaration shadows a local variable [-Wshadow]
for (int i = 15; i <=20 ; i++)
and
source.cpp:6:26: warning: unused variable 'i' [-Wunused-variable]
vector arrmain; int i,j;
Beside those, you have a logical issue in your code:
for values to check
if value is ok
print all known correct values
This will result in: 16, 16, 20 when ran.
Instead, you want to change the scope of the printing so it doesn't print on every match.
Finally, the bug you are seeing:
for(j=0; j<=arrmain.size(); j++)
{
cout <<arrmain[i]<< " "<<endl;
}
This bug is the result of poor naming, let me rename so you see the problem:
for(innercounter=0; innercounter<=arrmain.size(); innercounter++)
{
cout <<arrmain[outercounter]<< " "<<endl;
}
Now, it should be clear that you are using the wrong variable to index the vector. This will be indexes 16 and 20, in a vector with max size of 2. As these indexes are out-of-bounds for the vector, you have undefined behavior. When using the right index, the <= also causes you to go 1 index out of the bounds of the vector use < instead.
Besides using better names for your variables, I would recommend using the range based for. This is available since C++11.
for (int value : arrmain)
{
cout << value << " "<<endl;
}
The main issues in your code are that you are (1) using the wrong variable to index your vector when printing its values, i.e. you use cout <<arrmain[i] instead of cout <<arrmain[j]; and (2) that you exceed array bounds when iterating up to j <= arrmain.size() (instead of j < arrmain.size(). Note that arrmain[arrmain.size()] exceeds the vector's bounds by one because vector indices are 0-based; an vector of size 5, for example, has valid indices ranging from 0..4, and 5 is out of bounds.
A minor issue is that you print the array's contents again and again while filling it up. You probably want to print it once after the first loop, not again and again within it.
int main()
{
vector<int> arrmain;
for (int i = 15; i <=20 ; i++)
{
//checking which numbers are divisible by 4
if (i%4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
}
}
//output the elements in the vector
for(int j=0; j<arrmain.size(); j++)
{
cout <<arrmain[j]<< " "<<endl;
}
return 0;
}
Concerning the range-based for loop mentioned in the comment, note that you can iterate over the elements of a vector using the following abbreviate syntax:
// could also be written as range-based for loop:
for(auto val : arrmain) {
cout << val << " "<<endl;
}
This syntax is called a range-based for loop and is described, for example, here at cppreference.com.
After running your code, I found two bugs which are fixed in code below.
vector<int> arrmain; int i, j;
for (int i = 15; i <= 20; i++)
{
//checking which numbers are divisible by 4
if (i % 4 == 0)
{ //if number is divisible by 4 inserting them into arrmain
arrmain.push_back(i);
//output the elements in the vector
for (j = 0; j < arrmain.size(); j++) // should be < instead of <=
{
cout << arrmain[j] << " " << endl; // j instead of i
}
}
}
This code will output: 16 16 20, as you are printing elements of vector after each insert operation. You can take second loop outside to avoid doing repeated operations.
Basically, vectors are used in case of handling dynamic size change. So you can use push_back() if you want to increase the size of the vector dynamically or you can use []operator if size is already predefined.
Create a 3x3x3 array. Fill it with random values from 0 to 9. Output the array. Find output the 3 smallest and the 3 largest values. I continue to get erros from the compiler along with it stating issues with my initialization. I do not know why.
`#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void initialize(int x[3][3][3]) int column; int row; int layer; int large1;
void find(int x[3][3][3]); //to find number to fill
int main(){
srand(time(NULL));
int x[3][3][3];
int large1, large2, large3, small1, small2, small3, row, column, layer;
initialize(x[3][3][3]);
int x = RAND() % 0 + 10;
}
void initialize(int x[3][3][3]){
int large1, large2, large3, small1, small2, small3;
large1 = large2 = large3 = INT_LARGE;
for (int r = 0; r < 3; r++){
for (int c = 0; c < 3; c++){
for (int l = 0; l < 3; l++){
if (x[r][c][l]>large1){
large3 = large2;
large2 = large1;
large1 = x[r][c][l];
}
}
}
}
cout << large1 << large2 << large3 << endl;
system("pause");
}
`
remove junk ` at the beginning and the end of the code
add a semicolon between void initialize(int x[3][3][3]) and int column; int row; int layer; int large1;
initialize(x[3][3][3]); is bad because it access out of range. use initialize(x);
in int x = RAND() % 0 + 10; there are three errors:
x conflicts with int x[3][3][3]; Please change its name.
RAND() is not in the standard. Did you mean rand()?
Do not devide an integer by 0.
INT_LARGE is not defined. Please define it somewhere before using.
without an error message it's hard to guess at what's going wrong.
That said, int x = RAND() % 0 + 10; stood out like a beacon, so I'm guessing that's your problem. You can't use modulus (or divide) with 0, and modulus goes before addition. You can fix this with parenthesis
The first problem is that your declaration of initialize doesn't end with a semicolon but is followed by ... ]) int column; int row; int layer; int large1;. That doesn't parse.
The second problem is that the int x = RAND line is entirely pointless. It redefines x and would happen after initialize. Which is a bad name, because it doesn't initialize anything but instead sorts the elements.
At this point, you really should go back to your books, and then back to the high-level task. Make sure that initialize actually initializes x, and then put the actual sorting logic in find. It looks like you were asked to complete a program, and you entirely forgot about find.
Problem Statement
Mark is an undergraduate student and he is interested in rotation. A conveyor belt competition is going on in the town which Mark wants to win. In the competition, there's A conveyor belt which can be represented as a strip of 1xN blocks. Each block has a number written on it. The belt keeps rotating in such a way that after each rotation, each block is shifted to left of it and the first block goes to last position.
There is a switch near the conveyer belt which can stop the belt. Each participant would be given a single chance to stop the belt and his PMEAN would be calculated.
PMEAN is calculated using the sequence which is there on the belt when it stops. The participant having highest PMEAN is the winner. There can be multiple winners.
Mark wants to be among the winners. What PMEAN he should try to get which guarantees him to be the winner.
Definitions
PMEAN = (Summation over i = 1 to n) (i * i th number in the list)
where i is the index of a block at the conveyor belt when it is stopped. Indexing starts from 1.
Input Format
First line contains N denoting the number of elements on the belt.
Second line contains N space separated integers.
Output Format
Output the required PMEAN
Constraints
1 ≤ N ≤ 10^6
-10^9 ≤ each number ≤ 10^9
Code
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main (void)
{
int n;
cin>>n;
vector <int> foo;
int i = 0,j = 0,k,temp,fal,garb=0;
while (i < n)
{
cin>>fal;
foo.push_back(fal);
i++;
}
vector<int> arr;
//arr.reserve(10000);
for ( i = 0; i < n; i++ )
{
garb = i+1;
arr.push_back(garb);
}
long long product = 0;
long long bar = 0;
while (j < n)
{
i = 0;
temp = foo[0];
while ( i < n-1 )
{
foo[i] = foo[i+1];
i++;
}
foo[i] = temp;
for ( k = 0; k < n; k++ )
bar = bar + arr[k]*foo[k];
if ( bar > product )
product = bar;
j++;
}
return 0;
}
My Question:
What I am doing is basically trying out different combinations of the original array and then multiplying it with the array containing the values 1 2 3 ...... and then returning the maximum value. However, I am getting a segmentation fault in this.
Why is that happening?
Here's some of your code:
vector <int> foo;
int i = 0;
while (i < n)
{
cin >> fal;
foo[i] = fal;
i++;
}
When you do foo[0] = fal, you cause undefined behavior. There's no room in foo for [0] yet. You probably want to use std::vector::push_back() instead.
This same issue also occurs when you work on vector<int> arr;
And just as an aside, people will normally write that loop using a for-loop:
for (int i=0; i<n; i++) {
int fal;
cin >> fal;
foo.push_back(fal);
}
With regards to the updated code:
You never increment i in the first loop.
garb is never initialized.
I wrote a multiplication table like this:
#include <iostream>
#include <conio.h>
using namespace std;
int main(){
int table[9][9], i, j;
for (i = 0; i < 10; ++i){
for (j = 0; j < 10; ++j)
{
table[i][j] = (i + 1) * (j + 1);
cout << table[i][j] << "\t";
}
cout << endl;
}
_getch();
return 0;
}
And when I run it it gives me the right answer but when I press a key it throws this error:
run time check faliure #2-stack around the variable table was corrupted
But it doesn't throw that error when I change the code to this:
......
int main(){
**int table[10][10]**, i, j;
for (i = 0; i < 10; ++i){
......
If they both give the same answer then what's the difference??
You are overflowing your arrays, The max index in bounds is 8 (since the indices are zero based and you defined 9 cells as your dimensions size so 8 will be the last cell in each dimension) and your for loop can reach till 9 (including 9) which will cause an overflow.
The snippet int table[9] declares an array of size 9, that means valid indices are actually 0-8. But your loop iterates from 0 to 9. This causes a write into an invalid memory region (which doesn't belong to your array), therefore corrupting your stack.
Now you actually have a two dimensional array, but the problem remains the same.
You're going outside the array in your for loops. They should be:
for (i = 0; i < 9; ++i){
for (j = 0; j < 9; ++j)
The array indexes run from 0 to 8, but you were going up to 9 because your conditions were i < 10 and j < 10.
Arrays in C/C++ start with 0 index.
When you declare table[9][9] you reserve memory for 9x9 array with indexes 0..8, 0..8
but in for loop your upper index is 9 - it is out of array range
I guess you should declare table like you pointed:
int table[10][10];
You are accessing out of array's range element.
Your array is a 9x9 table but you are trying to access 10x10 table.
So either use i<9 and j<9 in your both loops or increase your array size to table[10][10].
Hope this might help.
Rule of thumb: in for loops, N in (i = 0; i < N; i++) clause should (almost always) be equal to the corresponding array's length. When you see either i <= N or i < N + 1, it's (most often) a sign of the dreaded off-by-one bug.