Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Laskulausekkeen laskeminen

msdos464 [01.08.2005 17:07:22]

#

Tämä javapätkä siis laskee lausekkeen arvon, lauseke voi sisältää matemaattisia funktioita, kertomia ( ! ), potensseja, desimaalilukuja (desimaaliPISTE, ei pilkku), sisäkkäisiä sulkuja sekä tietty peruslaskutoimituksia.

Virheenkäsittelyä ei ole, joten jos esim. lasketaan (-3)^0.5 niin ohjelma pukkaa ruman virheilmoituksen. Bugeja ei pitäisi paljoa olla, mutta joissain tapauksissa saattaa olla häikkää.

public class laskin
	{
	static String[] math = {"sin", "cos", "tan", "round", "abs", "sum"}; // tuettavat matemaattiset funktiot
	public static void main(String[] args)
		{
		System.out.println("\ntulos=" + laske("round(abs(3!*tan(sum(3!)))^.5*100)+5*2", 1));
		}
	public static String laske(String lasku, int ind) // ind liittyy välivaiheiden tulostukseen
		{
		String tulos = "", tmp1 = "";
		int a, b=0, c, m=0, m2=1, j=0, i, l, raja = lasku.indexOf(")"), raja2, des=0;
		double tmp = 0;
		boolean neg = false, n = false, desim = false, math_l = false;

		/* poista kommentti jos haluat nähdä miten lasku etenee
		for (a = 1; a < ind; a++)
			System.out.print(" ");
		System.out.println("laskuun="+lasku+", ind="+ind); */

		if (raja > -1) // jos löytyy sulkuja
			{
			String tmp2 = lasku.substring(0, raja);	// pätkä ennen ) sulkua
			raja2 = tmp2.lastIndexOf("("); // pätkä ennen ( sulkua

			// lasketaan sulkujen sisällä olevan lausekkeen arvo, sijoitetaan se edelliseen lausekkeeseen ja palautetaan tulos
			return laske(lasku.substring(0, raja2)+laske(tmp2.substring(raja2+1, tmp2.length()), ind+1)+lasku.substring(tmp2.length()+1, lasku.length()), ind+1);
			}
		for (i = 0; i < math.length; i++) // katsotaan onko joitain matemaattisia funktioita käytetty
			{
			for (a = 0; a < lasku.length()-math[i].length(); a++)
				{
				math_l = true;
				for (b = 0; b < math[i].length() && math_l; b++) // voisi olla substringillä järkevämpi
					if (lasku.charAt(a+b) != math[i].charAt(b))
						math_l = false;
				if (math_l)
					math_l = (num(lasku.charAt(a+b)-48) || lasku.charAt(a+b) == '-');
				if (math_l)
					{
					tmp = des = 0;
					c = a+math[i].length();
					desim = false;

					while (c < lasku.length() && (num(lasku.charAt(c)-48) || (lasku.charAt(c) == '-') && c == a+math[i].length()))
						{
						if (lasku.charAt(c) != '.' && lasku.charAt(c) != '-')
							{
							tmp = tmp * 10 + lasku.charAt(c) - 48;
							if (desim)
								des++;
							}
						else if (lasku.charAt(c) == '.')
							desim = true;
						c++;
						}
					tmp = 1.0*tmp/Math.pow(10, des);
					if (lasku.charAt(a+b) == '-')
						tmp = -tmp;
					tmp1 = lasku.substring(0, a);
					double luk=0;

					// katsotaan mikä funktio on kyseessä

					if (i == 0)
						luk = Math.sin(tmp);
					else if (i == 1)
						luk = Math.cos(tmp);
					else if (i == 2)
						luk = Math.tan(tmp);
					else if (i == 3)
						luk = Math.round(tmp);
					else if (i == 4)
						luk = Math.abs(tmp);
					else if (i == 5)
						luk = sum(tmp);

					if (c<lasku.length())
						tmp1 = lasku.substring(c, lasku.length());
					else
						tmp1 = "";
					return laske(lasku.substring(0, a)+luk+tmp1, ind+1);
					}
				}
			}

		for (a = 0; a < lasku.length(); a++)
			if (!num(lasku.charAt(a)-48) && a > 0)
				{
				n = true;
				if (lasku.charAt(a) != '!' && num(lasku.charAt(a-1)-48) || lasku.charAt(a-1) == '!')
					m++;
				}
			else if (num(lasku.charAt(a)-48) && n)
				{
				m2++;
				n = false;
				}
		double[] luvut = new double[m2];
		char[] merkit = new char[m];
		m=0;
		for (a = 0; a < lasku.length(); a++)
			if (num(lasku.charAt(a)-48) && lasku.charAt(a) != '.')
				{
				tmp = 10*tmp + lasku.charAt(a)-48;
				if (desim)
					des++;
				}
			else if (neg(lasku, a))
				neg = true;
			else if (lasku.charAt(a) == '!')
				{
				tmp = 1.0*kert(tmp/Math.pow(10, des));
				des = 0;
				}
			else if (lasku.charAt(a) == '.')
				desim = true;
			else
				{
				merkit[m] = lasku.charAt(a);
				luvut[m] = 1.0*tmp/Math.pow(10, des);
				if (neg)
					{
					luvut[m] = -luvut[m];
					neg = false;
					}
				tmp = des = 0;
				desim = false;
				m++;
				}
		luvut[m] = 1.0*tmp/Math.pow(10, des);
		if (neg)
			{
			luvut[m] = -luvut[m];
			neg = false;
			}
		// katsotaan mitä seuraavaksi lasketaan
		if (lasku.indexOf("!") > -1)
			{
			for (a = 0; a < m; a++)
				tmp1 += (""+luvut[a])+merkit[a];
			return laske(tmp1+luvut[a], ind+1);
			}
		for (a = 0; a < merkit.length; a++)
			if (merkit[a] == '^')
				{
				for (b = 0; b < a; b++)
					tmp1 += (""+luvut[b]) + merkit[b];
				tmp1 += Math.pow(luvut[a], luvut[a+1]);
				for (b++; b < merkit.length; b++)
					tmp1 += (""+merkit[b]) + luvut[b+1];
				return laske(tmp1, ind+1);
				}
		for (a = 0; a < merkit.length; a++)
			if (merkit[a] == '*')
				{
				for (b = 0; b < a; b++)
					tmp1 += (""+luvut[b]) + merkit[b];
				tmp1 += luvut[a] * luvut[a+1];
				for (b++; b < merkit.length; b++)
					tmp1 += (""+merkit[b]) + luvut[b+1];
				return laske(tmp1, ind+1);
				}
			else if (merkit[a] == '/')
				{
				for (b = 0; b < a; b++)
					tmp1 += (""+luvut[b]) + merkit[b];
				tmp1 += luvut[a] / luvut[a+1];
				for (b++; b < merkit.length; b++)
					tmp1 += (""+merkit[b]) + luvut[b+1];
				return laske(tmp1, ind+1);
				}
		for (a = 0; a < merkit.length; a++)
			if (merkit[a] == '+')
				{
				for (b = 0; b < a; b++)
					tmp1 += (""+luvut[b]) + merkit[b];
				tmp1 += luvut[a] + luvut[a+1];
				for (b++; b < merkit.length; b++)
					tmp1 += (""+merkit[b]) + luvut[b+1];
				if (merkit.length > 1)
					return laske(tmp1, ind+1);
				return tmp1;
				}
			else if (merkit[a] == '-')
				{
				for (b = 0; b < a; b++)
					tmp1 += (""+luvut[b]) + merkit[b];
				tmp1 += luvut[a] - luvut[a+1];
				for (b++; b < merkit.length; b++)
					tmp1 += (""+merkit[b]) + luvut[b+1];
				if (merkit.length > 1)
					return laske(tmp1, ind+1);
				else
					return tmp1;
				}
		if (merkit.length > 0)
			return tulos;
		else
			return lasku;
		}
	public static boolean neg(String lasku, int a)
		{
		if (lasku.charAt(a) == '-')
			if (a == 0)
				return true;
			else if (!num(lasku.charAt(a-1)-48) && lasku.charAt(a-1) != '!')
				return true;
		return false;
		}
	public static boolean num(int l) // onko osa lukua
		{
		return ((l >= 0 && l <= 9) || l+48 == '.');
		}
	public static double sum(double l) // laskee 1+2+3+...+l
		{
		return .5*l*(l+1);
		}
	public static void tulosta(char[] taul)
		{
		System.out.print("tulostus:");
		for (int a = 0; a < taul.length; a++)
			System.out.print(taul[a]+",");
		System.out.print("\n");
		}
	public static double kert(double a) // palauttaa kertoman a!
		{
		if (a % 1 > 0) // loistava virheen käsittely :)
			System.out.println("VIRHE");
		int t = 1;
		for (int l = 2; l <= a; l++)
			t*=l;
		return t;
		}
	}

Linkku [14.08.2005 16:53:30]

#

ihmesisennykset...

void funktio_a(int i)
    {
    ++i;
    if(i)
        {
        funktio_b(i);
        }
    }

Eihän tuota pysty millään lukemaan...

void funktio_a(int i)
{
    ++i;
    if(i)
    {
        funktio_b(i);
    }
}

Heti parani.

BlueByte [15.08.2005 02:42:05]

#

Aivan hyvät sievennykset. Älä valita juippi.

Sami [16.08.2005 00:39:19]

#

mikäs vika lausekkeessa (-3)^0.5 on? ihan hyvinhän siitä tulos tulee, joskin se on imaginääriluku, mutta tulos nyt kuitenkin :)

Kertoman laskemiseen taas kannattaisi käyttää tietotyyppinä vähintään long:ia, sillä int menee ympäri jo hyvinkin pienestä kertomasta (13!), long sentään pysyy vielä kärryillä luvun 20 kertomassa.

Jaska [16.08.2005 00:52:51]

#

Tuolla (-3)^0.5 tarkoitetaan ilmeisesti, että tällöin lausekkeeseen tulee eri arvoja riippuen mikä neliöjuuren haara valitaan. Nopeasti katsottuna ohjelmassa ei näytä otetun huomioon eri haarojen avulla saadut tulokset.

tkarkkainen [01.10.2005 13:30:55]

#

Jaska: Enpä usko. Lausekkeella (-3)^0.5 ei ole reaalilukuarvoa, koska ei ole olemassa reaalilukua, jonka toinen potenssi (tai mikään parillinen potenssi) olisi negatiivinen.

Toiseksi, neliöjuurella ei ole kahta haaraa, vaan sen arvo on aina positiivinen. Toisen asteen yhtälöstä tulee kaksi ratkaisua, koska:

x^2 = a =>
|x| = sqrt(a) =>
x = +- sqrt(a)

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta