PDA

View Full Version : کلاس معادلات چندجمله ای در جاوا



ehsan_faal
سه شنبه 28 بهمن 1393, 23:26 عصر
سلام دوستان.من یه برنامه نوشتم که معادله چند جمله ای رو از کاربر به عنوان رشته میگیره و ضرایب و درجه رو و هم چنین مقدار چند جمله ای رو توی نقطه ای که خودمون تعییین میکنیم برمیگردونه.
محدودیتی که داره اینه که حتما باید معادله رو به صورت استاندارد وارد کنیم یعنی جمله ای با بزرگترین توان اول بیاد بعد به ترتیب توانها کم بشن.
من یه مقدار راهنمایی میخوام که چطور :
1- اون محدودیت رو وردارم؟
2- چطور میتونم کاری کنم که اگه یه توانی دو بار یا بیشتر تکرار شد اتوماتیک ضرایب اون جمله ها با هم جمع بشن؟

package Priest;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class Equation {

private String Eq;
private final String[] C;
private int Deg;
private final String EqHolder;

public Equation(String Equation) {
this.Eq = Equation;
EqHolder = Equation;
Eq = Eq.replaceAll("[^0-9\\-\\.]+", " ");
Eq = Eq.replaceAll("-", " -");
this.C = Eq.split(" ");
}

public String SourceEquation() {
return EqHolder.toUpperCase().replaceAll("\\*", "").replaceAll("[a-zA-Z]", "\\*(X)").replaceAll("\\+", "\\ + ").replaceAll("\\-", "\\ - ");
}

public List<BigDecimal> CaptureCoeff() {
getDegree();
List<BigDecimal> Temp = new ArrayList<>();
for (String S : C) {
Temp.add(new BigDecimal(S));
}
int Location = Temp.indexOf(BigDecimal.valueOf(Deg));
List<BigDecimal> Coeffs = new ArrayList<>();
for (int Counter = Location - 1; Counter < Temp.size(); Counter += 2) {
Coeffs.add(Temp.get(Counter));
}
return Coeffs;
}

public int getDegree() {
int Degree = 0;
for (int Counter = 0; Counter < C.length; Counter += 2) {
if ((new Double(C[Counter])) != 0) {
Degree = new Integer(C[Counter + 1]);
this.Deg = Degree;
break;
}
}
return Degree;
}

public BigDecimal Evaluate(List<BigDecimal> Coefficients, int EvalPoint) {
BigDecimal Output = BigDecimal.ZERO;
for (int Index = 0; Index < Coefficients.size(); Index++) {
Output = Output.add(Coefficients.get(Index).multiply(BigDec imal.valueOf(EvalPoint).pow(Deg--)));
}
return Output;
}
}




کلاس اصلی:

package Priest;

public class MainClass {

public static void main(String[] args) {
String Str = "12.6x^4+6x^3+12*x^2-6*x^1-91";
Equation E = new Equation(Str);
System.out.println("Equation is: " + E.SourceEquation());
System.out.println("Coefficients :" + E.CaptureCoeff());
System.out.println("Polynomial Degree: " + E.getDegree());
int Target = 4;
System.out.println("Equation @ (X:" + Target + ")= " + E.Evaluate(E.CaptureCoeff(), Target));
}
}



اینم جوابی که میگیرم:

run:
Equation is: 12.6*(X)^4 + 6*(X)^3 + 12*(X)^2 - 6*(X)^1 - 91
Coefficients :[12.6, 6, 12, -6, -91]
Polynomial Degree: 4
Equation @ (X:4)= 3686.6
BUILD SUCCESSFUL (total time: 0 seconds)

با تشکر

محمد فدوی
پنج شنبه 30 بهمن 1393, 16:26 عصر
سلام. برنامه‌ی خوبیه ولی بهتر از اینا می‌تونستی بنویسیش.
من قبلا یه‌سری کلاس در مورد کار با چندجمله‌ای‌ها نوشتم که اگه پیداشون کردم و خواستی می‌تونم در اختیارت قرار بدم. چند تا نکته رو توی برنامه‌ت اضافه کنی خیلی بهتر می‌شه:

حالت‌ها مختلف ورود یک جمله رو (با کمی سختی) می‌تونی به برنامه‌ت اضافه کنی. مثلا وقتی ضریب x در رابطه یک یا منفی‌یک باشه معمولا ضریب رو نمی‌نویسیم. همینطور اگه توان x یک باشه نوشته نمی‌شه. یا مثلا وقتی توان x برابر صفر باشه دیگه کلا x نوشته نمی‌شه و اون جمله یه عدد ثابته.
اگه یک جمله رو توی یک شیء جداگونه در نظر بگیری در مورد ساده کردن عبارت (و مرتب کردنش) می‌تونی خیلی بهتر عمل کنی. مثلا کلاس Term اگه نماینده‌ی یه جمله باشه:



class Term {
private double coefficient;
private int power;

public Term(double coefficient, int power) {
this.coefficient = coefficient;
this.power = power;
}

@Override
public String toString() {
return String.format("%fx^%d", coefficient, power);
}

...

}



حالا میتونی کل چندجمله‌ای رو توی یک ساختمان داده مثل <ArrayList<Term یا <LinkedList<Term ذخیره کنی. و موقع ساده کردن هردو جمله‌ای که توان (Power) برابر داشته باشن میشه ضریب (Coefficient) اونها رو باهم جمع جبری کرد و در یک جمله نگهداری کرد. حتی میشه به سادگی براش متد جایگذاری رو نوشت که مقدار چندجمله‌ای رو به ازای یک مقدار x به دست بیاره، همینطور مشتق و انتگرال و حل معادله و... اتفاقا برنامه‌ی جالبی هم هست.


توی کلاست از متدهای رشته‌ها خیلی استفاده کردی(مثل replaceAll و...) و می‌دونی که هربار که از یکی از این متدها استفاده می‌کنی یه رشته از اول تخصیص حافظه و مقداردهی می‌شه و از اون مهمتر، هربار کل رشته حداقل یه‌بار بطور کامل پیمایش می‌شه! بهتره از تکنیک‌های فرمت‌کردن رشته (مثل Regexها) استفاده کنی یا رشته رو بصورت یک آرایه از کاراکتر دربیاری (با متد toCharArray) و خودت دستی با یکبار پیمایش کارای لازم رو روش انجام بدی.


موفق باشی.

ehsan_faal
جمعه 01 اسفند 1393, 13:14 عصر
ممنون .من خیلی سعی کردم یه چیز جمع و جور تر رو با regex پیاده کنم ولی هر چی گشتم چیزی که میخواستم رو نتونستم پیدا کنم و میدونم که هنوز جای کار داره.
اگه لطف کنی و کلاسهایی رو که قبلا نوشتی رو بذاری خیلی ممنون میشم. مطمئننا میتونه دربردارنده ی نکات آموزشی خوبی واسه افراد تازه کاری مثله من باشه.