I am working on some program and I have this array of ints lets say :
[cpp]
int [5] = {1,1,13,4,3}
[/cpp]
0-9 are numbers and 10 = +, 11 = -, 12 = * and 13 = /
So in this little array it should be :
1 1 / 4 3
and then the computer should make it
1/4 = 0.25
I tried some stuff here but I can't figure this out.
Had something like this :
[cpp]
int ParseCalc(int dAwnser,int Operator,int next)
{
switch(Operator)
{
case 10:
dAwnser+=next;
case 11:
dAwnser-=next;
case 12:
dAwnser*=next;
case 13:
dAwnser/=next;
}
return dAwnser;
}
[/cpp]
If anyone is interested I'm doing this trying to make a simple genetic algorithm
[QUOTE=quincy18;19304866]
[cpp]
int ParseCalc(int dAwnser,int Operator,int next)
{
switch(Operator)
{
case 10:
dAwnser+=next;
case 11:
dAwnser-=next;
case 12:
dAwnser*=next;
case 13:
dAwnser/=next;
}
return dAwnser;
}
[/cpp]
[/QUOTE]
Two things:
- you need a break; at the end of all the case: labels, otherwise the call will "fall through" the other cases. Meaning, if Operator is 10, and you don't have a break statement, then the case for 11, 12, and 13 will also be run.
- int(1) / int(4) = 0 (remainder 1, which could be gotten via modulo %). you need to make either one or both of those floating point (either float or double)
Yea, I just typed it out fast, I did it from my laptop, have the real code here ( I also said : "Had something like this :")
noticed in my real code I also forgot the breaks, thanks.
Did that fix things? (as well as the integer division thing)
No, its not errors or just not working Its just I need some more insight. I cant seem to get the idea to make it all work, like all the functions to search the string etc. so I should have added I was after some pseudocode how to do what I'm asking.
Is there any operator precedence, or is it just in the order they come in?
just the order they come in.
In that case, you can just iterate over your list as long as it has at least 3 elements. Look for any combination of <number, operator, number>. When you find one, evaluate it, remove those three elements from the list, and insert the result in their place.
Here's what the process would look like:
1 - 2 + 3 / 4
(1 - 2 combo works - evaluate it, insert)
-1 + 3 / 4
(-1 + 3 combo works - evaluate it, insert)
2 / 4
(2 / 4 combo works - evaluate it, insert)
0.5
(only 1 element left, must be the answer)
snip going to try some shit first, thanks.
[cpp]enum
{
OP_ADD = 10,
OP_SUB,
OP_MUL,
OP_DIV
};[/cpp]
That would make things a little easier on your brain, methinks :)
[QUOTE=jA_cOp;19319283][cpp]enum
{
OP_ADD = 10,
OP_SUB,
OP_MUL,
OP_DIV
};[/cpp]
That would make things a little easier on your brain, methinks :)[/QUOTE]
Definitely.
Also, since you're only using 4 different numbers, you might aswell use an unsigned char. Its range is 0-255, and you save a byte or 3.
[B]Edit:[/B]
Disregard this. Use enums instead.
or 7 if he's running x64
I've been trying something now and I got this :
the input of ParseAwnser is a reference to a array of numbers.
[cpp]
float ParseAwnserVector(std::vector<int> Calc)
{
float awnser;
for(int i=0; i < Calc.size() ;i+=3)
{
if(Calc.at(i+2) >= 0 && Calc.at(i+2) < 10) // Check if the target we want to add/mul etc. exists.
{
switch(Calc.at(i+1)) // Get the operator.
{
case ADD:
awnser+=Calc.at(i+2);
break;
case SUB:
awnser-=Calc.at(i+2);
break;
case MUL:
awnser*=Calc.at(i+2);
break;
case DIV:
if(!Calc.at(i+2) == 0)
{
awnser/=Calc.at(i+2);
}
break;
}
}
}
return awnser;
}
float ParseAwnser(int * awnser)
{
std::vector<int> Calc;
bool NotFound=true,LookForOpp=false;
for(int i=0; i < sizeof(awnser);i++)
{
if(LookForOpp)
{
if(awnser[i] > 9 && NotFound)
{
NotFound=false;
LookForOpp=false;
Calc.push_back(awnser[i]);
}
}
if(!LookForOpp)
{
if(awnser[i] < 10 && NotFound)
{
NotFound=false;
LookForOpp=true;
Calc.push_back(awnser[i]);
}
}
NotFound=true;
}
return ParseAwnserVector(Calc);
}
[/cpp]
Now I'm getting this :
First-chance exception at 0x776dfbae in Neural.exe: Microsoft C++ exception: std::out_of_range at memory location 0x002af7c0..
Unhandled exception at 0x776dfbae in Neural.exe: Microsoft C++ exception: std::out_of_range at memory location 0x002af7c0..
anyone ?
sizeof(awnser), aka, sizeof(int*), is not what you want to do. The size of a pointer is not the size of the value it points to, it's usually the same as the word size for your machine. In other words, on a 32 bit machine, a pointer is just 4 bytes. The result is that your loop gets 4 iterations, while your array contains less than 4 elements, so you try to index memory that isn't part of the array (out of bounds).
In plain C++ (and C), the convention is to pass the size of the array alongside the array itself.
[cpp]
float parseAnswer(int *answer, size_t len){ ... }
[/cpp]
Also note that it's spelled "answer", not "awnser".
I used this : a = ParseAwnser(tes, sizeof(&tes)/sizeof(int));
tes = pointer to array;
Errors:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
[QUOTE=quincy18;19349506]I used this : a = ParseAwnser(tes, sizeof(&tes)/sizeof(int));
tes = pointer to array;
Errors:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.[/QUOTE]
If tes is a pointer to an array (i.e. pointer to pointer), then you're taking the size of a pointer-to-pointer-to-pointer. Did you mean *, and not &? Either way, it's still not what you want. sizeof is a compile-time operator, don't use it for the size of anything that isn't clearly available at compile-time (because it can and will not do that), it won't do what you expect.
sizeof(&tes)/sizeof(int) is most likely 1 on your system though, so that's not the cause of the error. Post all the relevant code.
this was all the relevant code I think, anyways here is all the code :
Util.h
[cpp]
#include <vector>
#define AWNSER 104
#define CROSSOVER_RATE 0.7
#define MUTATION_RATE 0.001
#define CHROMO_LENGTH 200
#define GENE_LENGTH 4
enum
{
ADD = 10,
SUB,
MUL,
DIV
};
std::string RandomClamped(int size)
{
std::string str;
std::stringstream Stream;
Stream.str(str);
for(int i=0;i < size;i++)
{
Stream << rand()%2;
}
str = Stream.str();
return str;
}
int *BinaryStringToDecimal(std::string str)
{
std::string Buffstr;
int buff=0;
int number[CHROMO_LENGTH/GENE_LENGTH];
for(int i=0;i < (CHROMO_LENGTH/GENE_LENGTH);i++)
{
Buffstr = str.substr(i*GENE_LENGTH,GENE_LENGTH);
for(int k=0;k < GENE_LENGTH;k++)
{
buff = buff*2+atoi(Buffstr.substr(k,1).c_str());
}
number[i]=buff;
buff = 0;
}
return number;
}
float ParseAwnserVector(std::vector<int> Calc)
{
float awnser;
for(int i=0; i < Calc.size() ;i+=3)
{
if(Calc.at(i+2) >= 0 && Calc.at(i+2) < 10) // Check if the
{
switch(Calc.at(i+1)) // Get the operator.
{
case ADD:
awnser+=Calc.at(i+2);
break;
case SUB:
awnser-=Calc.at(i+2);
break;
case MUL:
awnser*=Calc.at(i+2);
break;
case DIV:
if(!Calc.at(i+2) == 0)
{
awnser/=Calc.at(i+2);
}
break;
}
}
}
return awnser;
}
float ParseAwnser(int * awnser, size_t len)
{
std::vector<int> Calc;
bool NotFound=true,LookForOpp=false;
for(int i=0; i < len;i++)
{
if(LookForOpp)
{
if(awnser[i] > 9 && NotFound)
{
NotFound=false;
LookForOpp=false;
Calc.push_back(awnser[i]);
}
}
if(!LookForOpp)
{
if(awnser[i] < 10 && NotFound)
{
NotFound=false;
LookForOpp=true;
Calc.push_back(awnser[i]);
}
}
NotFound=true;
}
return ParseAwnserVector(Calc);
}
[/cpp]
[cpp]
int main()
{
srand((unsigned)time(0));
chromosone test;
float a;
int * tes;
tes = BinaryStringToDecimal(test.bits);
a = ParseAwnser(tes, sizeof(&tes)/sizeof(int));
std::getchar();
return 0;
}
[/cpp]
Don't mind the awnser I'l change it when its working.
[QUOTE=nullsquared;19310955]In that case, you can just iterate over your list as long as it has at least 3 elements. Look for any combination of <number, operator, number>. When you find one, evaluate it, remove those three elements from the list, and insert the result in their place.
Here's what the process would look like:
1 - 2 + 3 / 4
(1 - 2 combo works - evaluate it, insert)
-1 + 3 / 4
(-1 + 3 combo works - evaluate it, insert)
2 / 4
(2 / 4 combo works - evaluate it, insert)
0.5
(only 1 element left, must be the answer)[/QUOTE]
Except you're forgetting BODMAS.
1+2*2 should be evaluated 1+(2*2), not (1+2)*2.
The easiest way to do this is with [url]http://en.wikipedia.org/wiki/Shunting_yard_algorithm[/url] and [url]http://en.wikipedia.org/wiki/Reverse_Polish_Notation[/url].
[QUOTE=Xera;19360641]Except you're forgetting BODMAS.
1+2*2 should be evaluated 1+(2*2), not (1+2)*2.
The easiest way to do this is with [url]http://en.wikipedia.org/wiki/Shunting_yard_algorithm[/url] and [url]http://en.wikipedia.org/wiki/Reverse_Polish_Notation[/url].[/QUOTE]
[QUOTE=nullsquared;19305485]Is there any operator precedence, or is it just in the order they come in?[/QUOTE]
[QUOTE=quincy18;19309994]just the order they come in.[/QUOTE]
So, no, you're wrong Xera. Thanks for playing.
Reverse Polish Notation is VERY FAST to parse (push/pop). It's also simple to use when you get used to it.
[QUOTE=nullsquared;19360703]So, no, you're wrong Xera. Thanks for playing.[/QUOTE]
My post was more of a general post suggesting he uses the SYA and RPN.
[QUOTE=Xera;19363015]My post was more of a general post suggesting he uses the SYA and RPN.[/QUOTE]
No, you said I forgot order of operations. Which I didn't, because I clearly affirmed whether order mattered with the OP.
Using SYA and RPN is not useful in his case, my suggested method is much quicker.
Added comments to some of the code, including the code that is most likely causing the error.
[cpp]
/*
In C++ (and C99), use constants instead of macros, they're safer and far less annoying when something goes wrong.
For example, AWNSER should be:
const int AWNSER = 104;
*/
#define AWNSER 104
#define CROSSOVER_RATE 0.7
#define MUTATION_RATE 0.001
#define CHROMO_LENGTH 200
#define GENE_LENGTH 4
/*
This function returns the address of a (non-static) local variable, which is not good.
If you insist on using a plain table for this, receive it as an out parameter instead.
Optionally, leave everything as it is right now, except add the "static" modifier to the number array.
static int number[CHROMO_LENGTH/GENE_LENGTH];
*/
int *BinaryStringToDecimal(std::string str)
{
std::string Buffstr;
int buff=0;
int number[CHROMO_LENGTH/GENE_LENGTH];
for(int i=0;i < (CHROMO_LENGTH/GENE_LENGTH);i++)
{
Buffstr = str.substr(i*GENE_LENGTH,GENE_LENGTH);
for(int k=0;k < GENE_LENGTH;k++)
{
buff = buff*2+atoi(Buffstr.substr(k,1).c_str());
}
number[i]=buff;
buff = 0;
}
return number;
}
[/cpp]
Your main function is fundamentally flawed, though, and it won't do you any good if you leave it as it is.
[cpp]
int main()
{
srand((unsigned)time(0));
chromosone test;
/*Small note, declare and initialize on one line.
If you want to know why, just ask, but I'll leave it at that for now*/
float a;
int * tes;
tes = BinaryStringToDecimal(test.bits);
/*the type of &tes is int**. int** is very likely the same size as int on your machine.
Addtionally, sizeof(&tes) and sizeof(int) are static (compile-time) expressions.
Thus, sizeof(&tes)/sizeof(int) is also a compile-time expression. It most likely evaluates to 1.*/
a = ParseAwnser(tes, sizeof(&tes)/sizeof(int));
std::getchar(); //Don't use cstdio just for this. iostream is preferred.
return 0;
}
[/cpp]
You should make it look more like this, if you insist on using C arrays (you should use a vector or some kind of awesome boost container instead if arrays confuse you):
[cpp]
int main()
{
srand((unsigned)time(0));
chromosone test;
const size_t tes_len = CHROMO_LENGTH/GENE_LENGTH;
int tes[tes_len];
BinaryStringToDecimal(test.bits, tes, tes_len);
float a = ParseAwnser(tes, tes_len);
std::getchar(); //I still wouldn't do this, though
return 0;
}
[/cpp]
Thanks dude, I only used arrays because well I just did, vectors make much more sense to me than arrays only aren't vectors much more memory expensive ? and how would you do this function : BinaryStringToDecimal
I mean this : Receive it as an out parameter instead.
Also the main function is just a test its not the code I'm going to use just for testing each function.
I'm thinking of rewriting everything and just paste the current useful code to a separate file.
[QUOTE=quincy18;19377613]Thanks dude, I only used arrays because well I just did, vectors make much more sense to me than arrays only aren't vectors much more memory expensive ?[/QUOTE]
Vectors are very light-weight with memory, only the size of the actual vector object ends up as overhead, and vector objects are really small anyway (like 24 bytes in a 32 bit executable?). However, vector uses dynamically allocated memory for the actual contained memory portion, which is variably CPU expensive to allocate. If your vector is of constant size, you can use the "reserve" member function of the vector to ease this overhead by allocating enough memory once, instead of spreading it out over several allocations (which is considerably more expensive).
If it's only gonna be run once or it's not in a bottleneck in your code (like graphics rendering routines), there is absolutely no perceivable difference in using a vector and an array.
For an easier to use statically sized array, look into boost::array. I haven't used it myself, but it looks like a perfect replacement for plain C arrays in almost all cases.
[QUOTE=quincy18;19377613]and how would you do this function : BinaryStringToDecimal
I mean this : Receive it as an out parameter instead.[/QUOTE]
You'd have to explain what BinaryStringToDecimal is actually supposed to do :v:
[QUOTE=quincy18;19377613]I'm thinking of rewriting everything and just paste the current useful code to a separate file.[/QUOTE]
Rewriting programs from scratch is rarely a good idea. Not telling you not to do it, but completely refactoring what you have is typically better.
I will use vectors instead of arrays then, and thanks for everything jA_c0p and with this :
[code]
and how would you do this function : BinaryStringToDecimal
I mean this : Receive it as an out parameter instead.
[/code]
I meant how do I pass it out as a parameter ?
[QUOTE=quincy18;19379056]I will use vectors instead of arrays then, and thanks for everything jA_c0p and with this :
[code]
and how would you do this function : BinaryStringToDecimal
I mean this : Receive it as an out parameter instead.
[/code]
I meant how do I pass it out as a parameter ?[/QUOTE]
You probably know this, but, arrays are so-called reference types. When you pass them to a function, only the address of the array is actually passed. That's why you can pass arrays as parameters of pointer type. That's also why you cannot return local arrays from functions, because only the address (as a pointer) is returned. Once the function returns, the stack will be changing, overwriting your array in the near future. The same behaviour applies to all local variables.
If you allocate the "number" array in main (the caller), as shown in one of my snippets above, the memory is still valid after BinaryStringToDecimal returns. So all you need to do is receive an array/pointer in BinaryStringToDecimal and write directly to that. When the function returns, the array will be filled. The expected size of the array is constant in your code, though, so passing the size alongside (as seen in the aforementioned snippet too) is not necessary.
Again, the alternative is to keep the "number" array where it is, but make it static. That will allocate it in global memory as opposed to the stack, and you can return it from the function safely. However, the same array is rewritten every time the function is called, invalidating its contents for previous callers with different input, so there will only ever be one instance of the "number" array if you make it static.
Sorry, you need to Log In to post a reply to this thread.