|
Hi,
Thank you, this was pretty much what I was thinking.
Do you have any ideas of the best way to store and sort the terms?
i.e. Should I use a struct for the elements? etc
I am still a beginner so any advice is most welcomed.
Kind Regards,
Stephen
|
|
|
|
|
Well, if you want to keep everything organized, maybe something like:
Element class: Stores a certain quantity of one element (i.e. 2 x H)
- Symbol
- Quantity
FormulaTerm class:
- List/Array of Elements (Each with a quantity)
- Text representation (Taken from the original formula, so it would know to represent 2H,O as "H2O" - More important for complex formulas that could have the same element multiple times)
- Quantity ("2" for "2H2O")
* Methods to add to other FormulaTerms, and to extract Elements (Multiply Quantity by each Element)
FormulaSide class:
- List/Array of FormulaTerms
* Method to combine with another FormulaSide to find the imbalances
|
|
|
|
|
I would probably set this up as two arrays, operands (left side) and results (right side). The arrays would contain structures that have two elements. The first element would be the multiplier for the particular item, and a dictionary with the element symbol as the key and the how much as the value.
The Dictionary object has a sort method built in, but you'll probably want to write your own to meet the requirements for sorting the particular elements according the the standard rules of chemistry. For example S comes before O for SO4.
I hope you find this approach helpful. If you have any questions, feel free to ask.
Scott E. Corbett
Software Engineer/Analyst
|
|
|
|
|
H2 + O2 = H2O
...
2H2 + O2 = 2H2O
hmm...
here's what i'd try for a first attempt:
1. parse the equation into left and right: "H2 + O2" and "H2O"
2. break it into molecules. left side "H2" "O2", right side "H20"
3. break the molecules into elements, pay attention to the counts
4. put each element into a container that will hold a label and a count (multiset, maybe)
ex.
left side:
Add H (container has: H:1)
Add H (container has: H:2)
Add O (container has: H:2, O:1)
Add O (container has: H:2, O:2)
right side:
Add H (container has: H:1)
Add H (container has: H:2)
Add O (container has: H:2, O:1)
5. compare the two containers to see find the differences . in this case the only difference is that the left has O:2 but the right has O:1, so there's the imbalance.
to balance, you have to adjust the molecule counts to get the element counts right... which is probably a bit of work
|
|
|
|
|
Just my tuppenceworth, the other answers have been good.
There is a full balancing method here[^]. It should transfer to an algorithm easily.
For the data representation I'd use two dictionaries, one for the number atoms on the LHS, the other for the right. You can make the chemical symbol the key, but you might also like an element class, that way you can do other handy stuff like work out the molar mass of the products etc.
I actually think the formula parser might be the hard part, but not having worked on the problem fully I could well be wrong.
|
|
|
|
|
No trial and error or inelegant algorithms are needed.
The problem can be solved by solving a system of linear equations, constructed like this:
As2S3 + HNO3 + H2O = H3AsO4 + H2SO4 + NO (unbalanced)
Should be turned into the system: (disclaimer: it was really quite late when I did this, so don't look at the numbers too closely the general principle should be sound though)
2 x0 + 0 x1 + 0 x2 - 1 x3 - 0 x4 - 0 x5 = 0 // for As
3 x0 + 0 x1 + 0 x2 - 0 x3 - 1 x4 - 0 x5 = 0 // for S
0 x0 + 1 x1 + 2 x2 - 3 x3 - 1 x4 - 0 x5 = 0 // for H
0 x0 + 1 x1 + 0 x2 - 0 x3 - 0 x4 - 1 x5 = 0 // for N
0 x0 + 3 x1 + 1 x2 - 4 x3 - 4 x4 - 1 x5 = 0 // for O
The variables correspond to how many times the molecule from the unbalanced equation is needed, the coefficients correspond to how many of the element are in the corresponding molecule.
If I did the math correctly, it gives:
3 As2S3 + 28 HNO3 + 4 H2O = 6 H3AsO4 + 9 H2SO4 + 28 NO
Does that help you any?
|
|
|
|
|
yep, linear equations it is; each different element gives one equation, and the unknowns are the amounts of each of the molecules.
the one funny thing is there could be more equations than unknowns, making either some of them redundant, or the problem unsolvable (obviously you can't balance H2O = H2SO4 ).
|
|
|
|
|
Luc Pattyn wrote: yep, linear equations it is
Geez, man. Is there anything you don't know?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I only know a tiny fraction of all there is to know, however I try and make up for it by applying simple logic.
And chemical formulae are all about preserving the elements...
|
|
|
|
|
Dear David1987,
Sorry, no, it does not help at all unfortunatly. I can't seem to work out what is going on here, although I suspect if I did it may prove a usefull way of approaching the problem.
Is there any chance you could show me what you mean, or maybe simplyfy it a little?
Thank you
|
|
|
|
|
Ok, let's take O2 + H2 = H2O then.
First I'll assign variables to the molecules:
O2 = x0
H2 = x1
H2O = x2
Then I build the equations, one for each element, the coefficients are how much of the current element is in the corresponding molecule:
H: 0 x0 + 2 x1 - 2 x2 = 0 // there is zero H in O2, 2 H in H2, 2 H in H2O
O: 2 x0 + 0 x1 - 1 x2 = 0 // there is 2 O in O2, zero O in H2, 1 O in H2O
The smallest solution where all variables are integers is x0 = 1, x1 = 2, x2 = 2, which corresponds to O2 + 2 H2 = 2 H2O
|
|
|
|
|
Hi,
OK that helps a little better, but I would have no idea how to implement this into code. It has gave me something to think about though.
Thank you again,
Stephen
|
|
|
|
|
As others have noted, the problem can be re-stated in terms of a system of linear equations. A particularly easy method to solve such systems (in relative terms, of course - it's a decent homework assignment for a second-year CS student) is the method of Gaussian Elimination[^].
Here is a Java implementation of what you are trying to build[^], conveniently packaged with a source code. The implementation is very easy to follow, even if you do not know Java (but do know some C#).
Good luck!
|
|
|
|
|
Thank you everyone for your help.
However, I think as a complete beginner, I may have bitten off more than I can chew, as I dont have a clue where to start based on the information provided.
Thank you again,
Stephen
|
|
|
|
|
If college chemistry can offer me anything it was that no equation balancer should be based on text input. The one I had to use was so bad I dared the prof. to fail me because I wasn't going to waste my time discovering how it wanted me to type.
Graphics and numeric up downs in a visually appealing manner are the way to go.
|
|
|
|
|
Lets start with a piece from the book:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TernaryOperator
{
class Time
{
int Year;
int Month;
int Date;
int Hour;
int Minute;
int Second;
public void DisplayCurrentTime()
{
Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}",
Month, Date, Year, Hour,Minute,Second);
Console.ReadKey();
}
public Time(System.DateTime dt)
{
Year = dt.Year;
Month = dt.Month;
Date = dt.Day;
Hour = dt.Hour;
Minute = dt.Minute;
Second = dt.Second;
}
}
class Program
{
static void Main(string[] args)
{
System.DateTime currentTime = System.DateTime.Now;
Time t = new Time(currentTime);
t.DisplayCurrentTime();
}
}
}
For the constructor portion, where I declared or created the reference in the constructor, the values aren't actively stored in my variables yet, am I right?
Year = dt.Year;
Month = dt.Month;
Date = dt.Day;
Hour = dt.Hour;
Minute = dt.Minute;
Second = dt.Second;
So that means my 'Time t = new Time(currentTime)' is storing the active vars into my constructor using the 'dt' reference?. Correct? I feel like I am almost lost.
|
|
|
|
|
Herboren wrote: the values aren't actively stored in my variables yet
Yes, they are, why do you think otherwise?
int s are value types.
|
|
|
|
|
Time t = new Time(currentTime);
The above code calls the constructor that takes a System.DateTime as input, and copies the values from the DateTime into the new object's variables. So you now have a Time object containing values that correspond to the currentTime object. The next line calls the DisplayCurrentTime() method on the Time object t , which displays the values previously stored.
Does that make sense?
The best things in life are not things.
|
|
|
|
|
Actually that made perfect sense and your put me back on track thank you. And these are all initialized explicitly, correct? And I can implicitly initialize it but changing 'int Second = 30;' as an initializer, not that I would want to but just to get the understanding of implicit and explicit.
|
|
|
|
|
Herboren wrote: And these are all initialized explicitly, correct?
Yes, statements of the form:
Year = dt.Year;
are taking a value from the input parameter (dt ) and allocating them to a variable within the current instance of the Time class; i.e. the object currently being constructed by the constructor.
Herboren wrote: And I can implicitly initialize it but changing 'int Second = 30;' as an initializer, not that I would want to but just to get the understanding of implicit and explicit.
I'm not sure I understand what you mean here: any statement of the form, variable = expression , is an explicit assignment, and can be placed anywhere, either within one of the class methods, or external to it when the access level of a variable allows. For a further discussion of explicit/implicit take a look here[^].
The best things in life are not things.
|
|
|
|
|
Hi,
Don't know whether it is right place to post this. If not, please suggest me the right forum.
I indexed the document using Lucene Indexer.
Each document contains the values for the Level, Parent, Description.
I would like to search the documents based on below conditions,
where Description contains "Ana", Level=0 and Parent not equal to "Move". I wrote the below code to satisfy those conditions
TermQuery qry = new TermQuery(new Term("Level", "0"));
WildcardQuery wQry = new WildcardQuery(new Term("Description", "*Ana*"));
QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Entity",
new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
Query qry1 = parser.Parse("Parent:NOT Move");
BooleanQuery boolQuery = (BooleanQuery)boolQuery.Combine(new Query[] { qry, wQry, qry1 });
boolQuery.Add(query, BooleanClause.Occur.MUST);
boolQuery.Add(wQry, BooleanClause.Occur.MUST);
boolQuery.Add(query3, BooleanClause.Occur.MUST);
hits = searcher.Search(boolQuery, 100);
qry and wQry are working but qry1 is not working. How to query Parent not equal to "Move".
Thanks in advance.
|
|
|
|
|
Ask the people you got the library from. It's is extremely unlikely that anyone that has any experience with your exact library is ever going to see your post.
|
|
|
|
|
I beleive you just need to use
BooleanClause.Occur.MUSTNOT
instead of
BooleanClause.Occur.MUST
Also don't use the NOT in the qry1.
|
|
|
|
|
Thank you, dmoses48. its working
|
|
|
|
|
Hi, suppose I have
var A = new[]
{
new {Name ="Car", N = 2},
new {Name ="Bike", N = 100}
};
var B = new[]
{
new {Name ="Car", N = 10},
new {Name ="Plane", N = 1}
};
I would like to to the following using LINQ syntax: Join A nd B getting a total collection summing also N where same objects are the same... to be clear the final output should be:
{Name ="Car", N = 12},
{Name ="Bike", N = 100},
{Name ="Plane", N = 1}
Thanks for your time
|
|
|
|
|