質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

逆ポーランド記法 単項演算

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 867

score 3

前提・実現したいこと

現在大学の課題で逆ポーランド 記法で記述された式をファイルから読み込み、 その結果をファイルに 書き出すプログラムをc言語で作成しています.math.hを用いずに単項演算であるマイナスの符号反転と絶対値||の実装を付け加えたいのですが,どのようにして組み込めば良いかが分かりません.どなたか教えていただけないでしょうか.お願い致します.

発生している問題・エラーメッセージ

単項演算の実装方法がわからない

該当のソースコード

#include <stdio.h>
#include <stdlib.h>
#define DUMMY -1//ダミーデータ
#define NODATA 0//データなし
#define EXISTDATA 1//データりあり

struct doubleCell{
    double data;//データ部
    struct DoubleCell * next; //ポインタ部
};

typedef struct doubleCell DoubleCell;
typedef DoubleCell* DoubleStack; //スタック型
typedef DoubleCell* Cell_P;

DoubleStack makeStack();//スタックの作成
void push(DoubleStack stack, double data);//データ挿入
double pop(DoubleStack stack);//データ取り出し
double isEmpty(DoubleStack stack);//空かのテスト
void calcToStack(FILE * fp,DoubleStack stack);//ファイルからのデータ入力
Cell_P makeCell(double n);//セル作成
void  result_fprint(FILE * fp, DoubleStack stack);
void printStack(DoubleStack stack);

int main(){
  DoubleStack stack;
  FILE *fp_in , *fp_out;
  stack=makeStack();
  fp_in=fopen("DoubleData","r");
  fp_out=fopen("ResultData","w");
  printf("ファイルへ計算結果を出力します.\n");
  calcToStack(fp_in, stack);
  result_fprint(fp_out, stack);
  fclose(fp_in);
  fclose(fp_out);
}

DoubleStack makeStack(){
    DoubleStack stack=(DoubleStack)makeCell(DUMMY);//ダミーセル
    stack->next=NULL;
    return stack;
}

double isEmpty(DoubleStack stack){
    if(stack->next==NULL) {
        return NODATA;
    }
    else {
        return EXISTDATA;
    }
}

Cell_P makeCell(double n){
    Cell_P new=(Cell_P)malloc(sizeof(DoubleCell));
    new->data=n;
    return new;
}

void push(DoubleStack stack ,double data){
    Cell_P new_cell=makeCell(data);
    new_cell->next=stack->next;
    stack->next=new_cell;
    return;
}

double pop(DoubleStack stack){
    Cell_P top=stack->next;
    double data;
    if(top!=NULL){
        data=top->data;
        stack->next=top->next;
        free(top);
        return data;
    }
    else{
        printf("No data\n");
        return -1;
    }
}

void  result_fprint(FILE * fp, DoubleStack stack){
  double result;
  result = pop(stack);
  fprintf(fp, "%f ", result);
  return;
}

void calcToStack(FILE * fp,DoubleStack stack){
  char tmp[10];
  double a;
  double b;
  while(fscanf(fp,"%s", tmp)!=EOF){
     printStack(stack);
     if(tmp[0] == '+') {
       a=pop(stack);
       b=pop(stack);
       push(stack, a+b);
     } else if(tmp[0] == '-') {
        a=pop(stack);
         b=pop(stack);
         push(stack, b-a);
     } else if(tmp[0] == '*') {
        a=pop(stack);
        b=pop(stack);
         push(stack, b*a);
      } else if(tmp[0] == '/') {
          a=pop(stack);
          b=pop(stack);
          push(stack, b/a);
      } else {
         push(stack, atof(tmp));
      }
  }
  return;
}

void printStack(DoubleStack stack){
    Cell_P p=stack->next;
    printf("(");
    while(p!=NULL){
        printf("%3.2f, ",p->data);
        p=p->next;
    }
    printf("]\n");
    return;
}

補足情報(FW/ツールのバージョンなど)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2020/08/20 01:28

    どんな入力に対しどんな結果を期待するのか、入力データの例とその時の出力を示してください。

    キャンセル

  • dogwanwan

    2020/08/20 02:00

    ただいま,他の方の回答で解決することができました.貴重なお時間頂戴してしまい大変申し訳ございません.

    キャンセル

回答 1

checkベストアンサー

+1

二項演算子はスタックからふたつの値を取り出して結果をスタックに積むのですから、取り出す値がひとつであればそれで単項演算子になります。

仮に単項マイナス (符号反転) を negate、絶対値をとるのを abs と名付けた場合、具体的には calcToStack の if 文の最後の else の前に以下のような分岐を付け加えればよいはずです。

} else if(!strcmp(tmp, "negate")) {
  a = pop(stack);
  push(stack, -a);
} else if(!strcmp(tmp, "abs")) {
  a = pop(stack);
  push(stack, a<0 ? -a : a);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/08/20 02:07

    この通りコードを書き込んだところしっかり動作させることができました!pushの引数の中で値を変換するという考えが思いつきませんでした.本当にありがとうございます!また,貴重なお時間ご頂戴してしまい申し訳ございませんでした.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る