3

更新: 残念ながら、私はこの課題を完了することができませんでしたが、締め切りは過ぎましたが、これを脇に置くにはあまりにも多くの時間を費やしたと感じており、私は解決策に近づいていることを知っています. これは私が過去数日間に作成したコードです

/* 

 "[5*sin(3*t+0.523),4*cos(2*t)]"

*/

import java.util.*;             // 
import javax.swing.*;           // 
import javax.swing.JFrame;      // lets me create the window 
import java.awt.Graphics;       // for drawing 
import java.awt.Point;          // allows the use of points 
import java.awt.Graphics2D;     // for drawing 
import javax.swing.JComponent;  // for drawing 
import javax.swing.JPanel;     // for drawing 
import java.lang.Math;         // for trig 
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;




public class Graph 
{   

//-------------------Queue---String----------------------------------------------------------------//

  public static double[] queue_str(String str, double[] results)
  {
    Queue<Character> token = new LinkedList<Character>();
    Queue<Double> numbers = new LinkedList<Double>();
    double[] t_vals = new double [5];
    int t_vals_len = t_vals.length;
    int numbers_sz = 0;
    int token_sz = 0;
    t_vals[0] = 7.0;
    t_vals[1] = 2.0;
    t_vals[2] = 3.0;
    t_vals[3] = 4.0;
    t_vals[4] = 3.0;
    char temp_token;
    char temp_char; 
    double p1_num = 0, temp_num = 0, p2_num = 0;

    if(results.length == 0){}

    for(int i = 0; i < str.length(); i++)
    {
        if(str.charAt(i) == '*' && str.charAt(i) != 't'  || str.charAt(i) == '+'&& str.charAt(i) != 't' || str.charAt(i) == '-' && str.charAt(i) != 't' || str.charAt(i) == '/' && str.charAt(i) != 't')
        {
            temp_token = str.charAt(i);
            token.add(temp_token);
            token_sz ++;
            String[] parts = str.split("\\" + String.valueOf(temp_token));
            String str1 = parts[0];
            String str2 = parts[1];


            if(str1.matches("-?\\d+(\\.\\d+)?"))
            {
                p1_num = Double.parseDouble(str1);
                numbers.add(p1_num);
                numbers_sz ++;
            }

            if(str2.matches("-?\\d+(\\.\\d+)?"))
            {
                p2_num = Double.parseDouble(str2);
                numbers.add(p2_num);
                numbers_sz ++;
            }
        }
            else if(str.charAt(i) == 't')
            {
                temp_token = str.charAt(i);

                String [] t_char = str.split(String.valueOf(temp_token));

                for(int k = 0; k < t_vals_len; k++)
                {
                    temp_num = t_vals[k];
                    numbers.add(temp_num);
                    numbers_sz ++;
                }
            }

    }
      double[] dbl_numbs = new double [numbers_sz];

      while(numbers.peek()!=null)
      {
           for (int iter = 0; iter < numbers_sz; iter++)
           {
             dbl_numbs [iter] = numbers.poll();
           }  
      }

         while(token.peek()!=null)
          {
               temp_token = token.peek();
               token.poll();

               if(temp_token== '+')
               {

                 eval_inner_add(dbl_numbs, numbers_sz);
                 results = eval_inner_add(dbl_numbs,numbers_sz);

               }
               else if(temp_token == '-')
               {

                eval_inner_add(dbl_numbs, numbers_sz);
               }
               else if(temp_token == '*')
               {
                 results  = eval_inner_multi(dbl_numbs, numbers_sz);

               }
               else if(temp_token == '/')
               {

                eval_inner_div(dbl_numbs, numbers_sz);
               }
          }

      return t_vals;
  }
//-----------------Removing---Brackets-------------------------------------------------------------//  
  public static String [] remove_brackets(String remove_brack)
  {
     String [] substring = remove_brack.split ("[\\[,\\]]");
     String rest_of_str = substring [1];
     String rest_of_str_2 = substring [2];
     return new String [] {rest_of_str,rest_of_str_2};
  } 
//-----------------Removing---Parenthesis-------------------------------------------------------------//    
   public static String [] remove_paren(String remove_paren)
  {
     String [] substring = remove_paren.split ("[\\(,\\)]");
     String rest_of_str = substring [0];
     String rest_of_str_2 = substring [1];
     return new String [] {rest_of_str,rest_of_str_2};
  } 
//---------------Retrieving--Far-Left--Number----------------------------------------------------//  
  public static double get_first_exp (String get_left_exp)  
  {
    double eval_num = 0;

    if(get_left_exp.matches("[-]"))
    {
        String [] check_neg = get_left_exp.split("[\\-]");
        String neg_num = check_neg[0];
        eval_num = Double.parseDouble(neg_num);
        eval_num = eval_num * (-1.0);
        return eval_num;
    }
    else
    {
        String [] parts = get_left_exp.split("[\\/,\\*,\\+]");
        String sub_str_1 = parts [0];
        eval_num = Double.parseDouble(sub_str_1);
        return eval_num;
    }
  }
//-------------Evaluating--equations--containing--sine----------------------------------------//

  public static double eval_sin (String sin_eq)
  {
   double number = 0;
   String [] split = remove_paren(sin_eq);
   String inner_exp = split[1];
   double [] nothing = new double [0];

   number = get_first_exp (sin_eq);
   queue_str(inner_exp, nothing);
   return number;
  }

//-------------Evaluating--equations--containing--cosine----------------------------------------//
  public static double eval_cos (String cos_eq)
  {
   double number = 0;
   double [] nothing = new double [0];
   String [] split = remove_paren(cos_eq);
   String inner_exp = split[1];

   number = get_first_exp (cos_eq);
   queue_str(inner_exp, nothing);
   return number;
  }
//---------------Evalutating--points-------------------------------------------------------------//  
  public static double[] eval_inner_multi (double [] numbers, int numbers_sz)
  {
   String nothing  = "";
   double[] results = new double [numbers_sz];
   double  first_num = numbers[0];
   System.out.println(first_num);

    for(int i = 1; i < numbers_sz-1; i++)
    {
     results[i] = first_num * numbers[i]; 
     System.out.println(results[i]);
    }
      queue_str(nothing,results);
      return results; 
  }

  public static double[] eval_inner_add (double [] numbers, int numbers_sz)
  {
   String nothing  = "";
   double[] results = new double [numbers_sz];
   double  first_num = numbers[0];


    for(int i = 1; i < numbers_sz-1; i++)
    {
     results[i] = first_num + numbers[i]; 
     System.out.println(results[i]);
    }
      queue_str(nothing,results);
      return results; 
  }

  public static double[] eval_inner_sub(double [] numbers, int numbers_sz)
  {
   double[] t_vals = new double [5];
   return t_vals; 
  }

  public static double[] eval_inner_div(double [] numbers,int numbers_sz)
  {
   double[] t_vals = new double [5];
   return t_vals; 
  }
//------------------------------Main------------------------------------------------------------------------//  
  public static void main(String[] args) 
    {
      String left_exp = "";
      String right_exp = "";
      double left_sin_num , right_sin_num, left_cos_num, right_cos_num = 0;

      for(String s: args)  // taking in user input for command line 
      {
           String [] new_str  =  remove_brackets(s);
           left_exp = new_str[0];
           right_exp = new_str[1];
      }

      if(left_exp.contains("sin")) // add SINE, SIN, COSINE, COS
      {
           left_sin_num = eval_sin(left_exp);
      }
      else if (right_exp.contains("sin"))
      {
           right_sin_num = eval_sin(right_exp);
      }
      if (right_exp.contains("cos"))
      {
           right_cos_num = eval_cos(right_exp);
      }
      else if (left_exp.contains("cos"))
      {
           left_cos_num = eval_cos(left_exp);
      }

    }

}

この課題の目的は、パラメトリック方程式を評価し、座標を結合してグラフをプロットするプログラムを作成することでした。私が抱えている問題は、評価されるために queue_str() 関数で double の配列を送信するときです。コンテンツを正しく queue_str() に送り返して 2 番目のオペランドで評価することはできません。たとえば、トップ コメントのサンプル関数を考慮すると、3*t を送信できます。ここで、t_vals は 3 を乗算するテスト ケースです。 . この場合、配列の最初と最後の要素を考慮する必要があるため、配列のサイズを-1にする必要があります。これは、この式を適切に評価するにはどうすればよいですか? 助けていただければ幸いです。この段落についてお詫び申し上げます。これを機能させるのに非常に近いことを知っています。

4

2 に答える 2

5

式を左から右に評価するのではなく、ツリーに解析する必要があります。

  sin
   |
   +
  / \
  *  5
 / \
2  t

これについては、こちらで詳しく説明しています。

于 2013-03-17T23:50:51.563 に答える
0

私はあなたと同様の問題を解決していました。すべての順序を正しくするために、レクサーとパーサーを使用しました。Python では、PLY を使用しました。これについては、 http : //www.dabeaz.com/ply/ http ://www.dabeaz.com/ply/ply.html

ドキュメントでは、パーサー中に「舞台裏」で何が起こっているかをよく示しています: http://www.dabeaz.com/ply/ply.html#ply_nn22

私のトークナイザー/パーサー構造は、Java がその式を評価するために使用するのと同じ構造に触発されました。http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8

これまでパーサー構造に頭を悩ませたことがない場合は、慣れる必要があることがいくつかあります。そのような:

-ルート トークン - 式と呼びます - 番号、名前、関数呼び出し、またはその他の「コンポーネント」から昇格でき、「成長」して構造全体を「消費」し、他のすべてを折りたたむことができます。

-生の数値または名前が式になる前に通過する昇格されたトークンの複数のレベル - 単項演算子から優先順位の高いもの、優先順位の低いものへの各段階で、演算子を再度昇格させる前に適用できるかどうかを確認します。YACC のようなパーサーは、最大のものを選択できる場合、またはその選択が明確であることがわかっている場合にのみルールを適用することによってこれを機能させます。

- その再帰的な性質 - sin(...) の内部は引数リストであり、これは式または引数リスト、式であり、式自体は外側の式と同じくらい複雑になる可能性があります...そして関数呼び出しが発生すると、演算子のすべての優先レベルに対してチェックした後、式自体に昇格されます! 等々。

一般的に、PLY のドキュメントを読むと、これらすべてに頭を悩ませるのに役立ちます :) トークン化と解析を行わずに生の文字列/部分文字列操作で式の計算を行うことはできません。私をだますエッジケースが常にありました。

于 2013-03-17T23:56:33.283 に答える