i'm buisy learning myself to program and i'm trying to copy a game that i find fun to play to c++ (basicly just for the sake of learning. So if i formulated the question wrong please forgive me.)
Now i have an issue with randomising a 2 dimentional array. The thing is that i manage it partially to get it to work but i just fail to reason how i can make it fully work.
The code:
// Random generate and return nr 2 or 4 on calling this function.
int startValue1(){
srand(time(NULL));
int arrayStart[2] = {2, 4};
int randIndex = rand() % 2;
return arrayStart[randIndex];
}
// Random generate and return nr 4 or 2 on calling this function.
int startValue2(){
srand(time(NULL));
int arrayStart[2] = {4, 2};
int randIndex = rand() % 2;
return arrayStart[randIndex];
}
int tester(){
//generate 2 start values and assign to variables
int a = startValue1();
int b = startValue2();
//initialize 2 dimentional array and add the 2 starting numbers.
int board[4][4] = {{a,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,b}
};
// print out the board in console to check/test the function(S).
for(int row = 0; row<4; row++){
for (int column = 0; column<4; column++){
cout << board[row][column] << " ";
}
cout << endl << endl;
}
cout << endl;
//Randomize the elements in the 2 dimentional array.
random_shuffle(board, board +4) ;
//print out the array to console after the board is randomised (for testing/checking only)
for(int row = 0; row<4; row++){
for (int column = 0; column<4; column++){
cout << board[row][column] << " ";
}
cout << endl << endl;
}
}
The output of this looks something like this :
0 0 0 0
0 0 0 0
4 0 0 0
0 0 0 2
The problem is that the elements only arrange verticaly and never horizontally as if the random_shuffle function only works on one dimention.
I did read up on that function but i just fail to see/reason how i can make it work on a 2 dimentional array.
Hopefully someone can give me some pointers or directions to the info on how to solve this.
Personally i thought that it would be best if i just now somehow arrange the elements horizontally and continue from there. But if there is a better solution i'm al open for it ofcourse.
(In case for anyone who wonders: i'm trying to remake the webgame 2048 in c++ and i plan to use this code to initialize the board and make it ready to play.
Most likely it's not the best approach to solve this but i'm trying to tackle one problem at the time and learn from it and just keep redoing the code till it works.)
Related
This question already has answers here:
The most efficient way to find mode in an array?
(4 answers)
Closed 1 year ago.
const int NUM_MAX = 100;
const int HOWMANY = 30;
int main()
{
vector<int> myVector;
int counters[NUM_MAX] = { 0 };
//to print out 15 numbers per line
int x = 15;
//seed random number generator
srand(time(0));
cout << "Array of 30 Random Numbers: "<< endl;
for (int i = 0; i < HOWMANY; i++)
{
int myRandom = rand() % NUM_MAX;
myVector.push_back(myRandom);
int thisVal = myVector[i];
cout << thisVal << " ";
if (i % x == 0)
cout << "\n";
}
cout << " " << endl;
return 0;
}
I'm just starting to learn about vectors and arrays, and my teacher has the counters array set up for us, but I'm not sure what to do with that. I have to find the number that occurs the most in the 30 random generated numbers, and I have to count how many times that number appeared. I'm very lost.
I think you make your problem harder for yourself, by making your problem easier and think easier you can solve your problems faster and as my friends said, in this problem you can define a array as a counter and count each number in its index, like said in the top of the page :)
What you have described is finding the mode of the array.
As #selbie mentioned, You need to increment counters[myRandom]++ and find the maximum value of the counters array. The position of the max value is the mode(Max occuring number) and the value is the number of time it has appeared.
For Eg: Lets take the MAX_VALUE as 5 and HOWMANY(bad choice on variable name though :P) as 10
Let random generated array be
1 5 3 2 1 3 4 3 3 3
So at each loop iteration , you will be updating counter variable as
counter[number]++. For Eg. in this case it will be
counter[0] = 0
counter[1] = 2
counter[2] = 1
counter[3] = 4
counter[4] = 1
counter[5] = 1
So, the maximum value of the array is at position 3 . So the mode( max occuring element ) is 3 and the number of times it appeared is 4.
NOTE IMHO, Your question states you are new to vectors and arrays. however as #selbie mentioned the question here is intended to check your lorgic on how will you compute mode rather than knowing the operations of a vector. programming at start may seem its more weighed towards fancy libraries and hard syntaxes, however its always the logical thinking ( algorithm ) that would be the backbone of all the coding problems.
I would like to convert a bunch of stock/forex indicators written in MQL4 (.mq4 files) to C++. Previously, I had only been programming in Python and had very little exposure to both MQL4 and C++. Furthermore, I am not at all aware of the ways to go about such a problem, and whether it is even feasible. (Although, worst case scenario, manually recoding them all should definitely be feasible.)
I took a simple indicator, the Simple Moving Average, as an example and started tinkering with it and running it using a C++ compiler. Knowing that the syntax of the two languages is highly similar, I thought this could be a relatively easy process, and even automable to some degree.
Here is the Simple Moving Average script extracted from the .mq4 file available at this link:
MA_Period=5;
void sma()
{
double sum=0;
int i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=Close[pos];
//---- main calculation loop
while(pos>=0)
{
sum+=Close[pos];
ExtMapBuffer[pos]=sum/MA_Period;
sum-=Close[pos+MA_Period-1];
pos--;
}
//---- zero initial bars
if(ExtCountedBars<1)
for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
}
And here is my C++ implementation, at the moment testing it on a short array arr[] representing the Close array in MQL4. Furthermore, I dropped MQL4's Bars and ExtCountedBars variables (as I want to run the indicator on static, historical data), and replaced ExtMapBuffer with an array called output[], with equal length as the "price" array arr[].
#include <iostream>
using namespace std;
int main()
{
int MA_Period=5;
int arr[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
double sum=0;
int i, pos=0;
int output[20];
cout << "Pos: " << pos << endl;
//---- initial accumulation
if(pos<MA_Period) pos=MA_Period;
for(i=1;i<MA_Period;i++,pos--)
sum+=arr[pos];
cout << "Sum of past " << MA_Period << " prices : " << sum << endl;
cout << "Pos = " << pos << endl;
//---- main calculation loop
while(pos>=0)
{
sum+=arr[pos];
output[pos]=sum/MA_Period;
sum-=arr[pos+MA_Period-1];
pos--;
}
for(int j=0;j<sizeof(output)/sizeof(output[0]);j++){
cout << "output[" << j << "] = " << output[j] << endl;
}
return 0;
}
The console output I'm gettign for the output array values are:
output[0] = 3
output[1] = 4
output[2] = 65535
output[3] = 1
output[4] = 1706671568
output[5] = 32766
output[6] = 4197523
output[7] = 0
output[8] = 2
output[9] = 0
output[10] = 4197613
output[11] = 0
output[12] = 124
output[13] = 0
output[14] = 0
output[15] = 0
output[16] = 4197536
output[17] = 0
output[18] = 4196352
output[19] = 0
which is clearly not correct. I tried retaining as much from the original MQL4 code when converting to C++ but now hit a roadblock as to why the output is massively different from the expected:
output[0] = nan
output[1] = nan
output[2] = nan
output[3] = nan
output[4] = 3
output[5] = 4
output[6] = 5
output[7] = 6
output[8] = 7
output[9] = 8
output[10] = 9
output[11] = 10
output[12] = 11
output[13] = 12
output[14] = 13
output[15] = 14
output[16] = 15
output[17] = 16
output[18] = 17
output[19] = 18
What am I missing / misunderstanding in the process of converting my MQL4 code to C++?
There are several problems with this code. The main issue is your use of indices i and pos. In particular, after the initial accumulation, pos is equal to 1, so the main calculation loop will only run one iteration before it is done. So only output[1] gets written to, the rest of the array is uninitialized, and may contain any value.
Also note that array indices in C start at zero. Your initial accumulation loop starts at 1, which is not what you want.
I would avoid having two variables for indices, and only use one. To initialize sum, write:
for (int i = 0; i < MA_Period; ++i) {
sum += arr[i];
output[i] = -1;
}
Then to do the remainder write:
for (int i = MA_Period; i < sizeof(output) / sizeof(output[0]); ++i) {
sum += arr[i];
sum -= arr[i - MA_Period];
output[i] = sum / MA_Period;
}
This will give you the expected output. Note that there is no way to get nan for the first 5 values, as an int can never be nan. If you make output an array of double it is possible though, for example using this line in the initial loop:
output[i] = 0.0 / 0.0;
As for why the original MQL4 code worked: it initializes pos to Bars - ExtCountedBars - 1, whereas you initialized it to 0 in your C++ version.
I am learning C++ and I am working on a project where I have a two dimensional vector[5][1]
vector[0][0] = 1
vector[1][0] = 2
vector[2][0] = 3
vector[3][0] = 4
vector[4][0] = 5
I then add a count to the second dimension
example:
vector[0][1] = 17
vector[1][1] = 24
vector[2][1] = 91
vector[3][1] = 2
vector[4][1] = 50
I want to cout the first dimension the second dimension number of times
So if I would cout vector[0][0] 17 times vector[1][0] 24 times etc.
I just started learning 3 weeks ago and the prof is incredibly unresponsive, so I would appreciate any and all feedback!
I have a two dimensional vector[5][1]
I assume your declaration is int vector[5][1] (but you should clarify in your question).
This means the valid index for the first dimension is from 0 to 4 inclusive. And for the second dimension the only valid index is 0.
You go out of bounds when you do vector[0][1] etc and as such you have Undefined Behavior. If you wish to store two elements in the second dimension then you need to have int vector[5][2].
Going back to your question. Assuming you fixed the declaration.
I want to cout the first dimension the second dimension number of times
Think how you would do that for a row
cout the first dimension
ok, so
std::cout << vector[row_idx][0];
... the second dimension number of times
So we repeat the above vector[row_idx][1] times. Easy peasy:
for (int repeat = 0; repeat < vector[row_idx][1]; ++repeat)
{
std::cout << vector[row_idx][0];
}
And now do this for each row:
std::size_t num_rows = 5;
for (std::size_t row_idx = 0; row_idx < num_rows; ++row_idx)
{
for (int repeat = 0; repeat < vector[row_idx][1]; ++repeat)
{
std::cout << vector[row_idx][0];
}
std::cout << endl;
}
I want to create a matrix of 5 lines and 5 columns which contains values from 1 to 9. The following programs displays numbers from 1 to 25 instead, when I input 5 to the program..
#include <iostream>
using namespace std;
int a[20][20], n, x = 0;
int main()
{
cout << "n=";
cin >> n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
{
a[i][j] = x+1;
x = x+1;
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
cout << a[i][j] << " ";
cout << endl;
}
}
I'm a c++ beginner, so maybe it's simple to do but i don't know how to make it show values from 1 to 9. This is the matrix I except:
1 2 3 4 5
6 7 8 9 1
2 3 4 5 6
7 8 9 1 2
3 4 5 6 7
There are some issues in your code.
C arrays or STL containers?
First off, a your matrix may only hold matrices as big as 20x20. Your program will silently fail if you enter n bigger than 20, because you will access memory out of bounds; which causes an undefined behavior (see other common UB cases here).
You may want to use a dynamic size array - A good way to achieve this is to use std::vector. Unfortunately, this isn't as comfortable to use as a C-style array with two dimensions - you can achieve the same access syntax using a std::vector<std::vector<int>>, but this is not very efficient (see this answer if you are interested why) nor quite comfortable.
The Boost C++ library provides a multidimensional array library. Once you get experienced enough, you may find an use in it.
<= or <? 0-index or 1-indexed?
Many programming languages today uses 0-indexing for arrays. This means the first element of the array is located at index 0, not 1. Some languages, such as Lua, doesn't do this.
This means you should iterate i and j from 0 to n. This also means n is excluded, so you should use <, not <=.
Filling the matrix with numbers from 1 to 9
Your code doesn't do anything so you get numbers from 1 to 9 - it only fills the matrix with numbers from 1 to n * n. You could change this using an if clause to set x every time it goes above 9:
if (x > 9) { x = 0; } // x = 0 because it will be 1 on the next iteration
That being said, there is more convenient, as #PMar's answer says. The modulo operator % will do the task as well.
a[i][j] = (x % 9) + 1;
x = (x % 9) + 1;
This way, you will get every number from 1 to 9.
Now, you can also do another cleanup: Why are you calculating x's next value, and only then setting it? You could assign the new x value before the assignment to your matrix's cell. This allows having clearer code, with less copy pasting, which implies better maintainability.
x = (x % 9) + 1;
a[i][j] = x;
Another code quality consideration
I cannot say if your original code source was indented like your question (before it was edited), but you should really indent your code, for the future you and other people that will have to read your code. It allows for much better readability.
Same goes for different parts of your code : Add some space! It only can get more readable if you make a clear distinction between even just expressions.
You need to use the modulus operator (%). If you want the values in the matrix to be as you have computed them, but only need to change the display, you would output the matrix values as follows:
cout << (a[i][j] % 10) << " ";
If you want the one-digit values to be in the matrix itself, you would instead change the increment on 'x' to the following:
x = (x+1) % 10;}
#include <iostream>
int main()
{
int a[5][5];
int x = 1;
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
if(x > 9)
x = 1;
a[i][j] = x;
x++;
}
}
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
if(a[i][j] < 10)
std::cout << " ";
std::cout << a[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
return 0;
}
I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.