
C言語でスタック(リスト構造)を使用した逆ポーランド記法のプログラムを作りたいのですが
計算式(例:1234+*+)が入力された場合、どのようにして数字と演算子を区別すればいいのでしょうか?
一応スタック構造の部分は、
#include <stdio.h>
#include <stdlib.h>
/*スタック構造*/
typedef struct stack
{
int max;
int ptr;
int *stk;
} Stack;
/*スタックの確保・初期化*/
int StackAlloc(Stack *s, int max)
{
s->ptr = 0;
if ((s->stk = calloc(max, sizeof(int))) == NULL)
{
s->max = 0;
return (-1);
}
s->max = max;
return (0);
}
/*スタック解放*/
void StackFree(Stack *s)
{
if (s->stk != NULL)
{
free(s->stk);
s->max = s->ptr = 0;
}
}
/*プッシュ*/
int StackPush(Stack *s, int x)
{
if (s->ptr >= s->max)
return (-1);
s->stk[s->ptr++] = x;
return (0);
}
/*ポップ*/
int StackPop(Stack *s, int *x)
{
if (s->ptr <= 0)
return (-1);
*x = s->stk[--s->ptr];
return (0);
}
/*データのピーク*/
int StackPeek(const Stack *s, int *x)
{
if (s->ptr <= 0)
return (-1);
*x = s->stk[s->ptr - 1];
return (0);
}
/*スタックの大きさを返却*/
int StackSize(const Stack *s)
{
return (s->max);
}
/*データを返却*/
int StackNo(const Stack *s)
{
return (s->ptr);
}
/*スタックは空か*/
int StackEmpty(const Stack *s)
{
return (s->ptr <= 0);
}
/*スタックは満杯か*/
int StackFull(const Stack *s)
{
return (s->ptr >= s->max);
}
/*スタックを空にする*/
void StackClear(Stack *s)
{
s->ptr = 0;
}
といった感じで仕上げています。
No.4ベストアンサー
- 回答日時:
つい2週間くらい前に逆ポーランドの処理コードを書きました。
言語はObjective-Cでしたけど。
記憶に新しいので助言します。
まず、逆ポーランドの処理では、数値も演算子もトークン(呼び方は一例)として
扱います。
C言語でしたら、トークンを構造体で表現するのが自然かと思います。
typedef enum {
TOKEN_TYPE_NUM,
TOKEN_TYPE_OPERAND
} token_type;
typedef struct {
token_type type;
int value; // 数値または演算子
} token;
そうすると、トークンは1234+*+の7つあるわけですから、tokenポインタが7つPushされた
スタックを作ります。
あとはルールに従ってPopとPushで処理していけばいいですよね。
> どのようにして数字と演算子を区別すればいいのでしょうか?
もうお分かりかと思いますが、一例を書きます。
token *t;
StackPop(s, &t);
if(t->type == TOKEN_TYPE_NUM){
// t->valueを数値として処理
}
if(t->type == TOKEN_TYPE_OPERAND){
// (char)t->valueを演算子として処理
}
最後に、ほかの方も指摘していますが、質問者様のコードはツリー型のスタックになっていません。
というか、スタック実装は通常リンクリストであってツリーにはしないです。
ツリーを使う処理として、二分探索木なんかが教科書にはよく登場します。
http://ja.wikipedia.org/wiki/2%E5%88%86%E6%8E%A2 …
スタックでは、通常ノードとノードがポインタで連結した構造をとります。
具体的にはこんなコードになるはずです。
http://www.freecprograms.com/lilink.htm
勉強用であればそのままでもいいかもしれませんが、とりあえずポインタのPush/Popが
できるように改造しないとjjk65536案は使えないですね。
No.3
- 回答日時:
>どのようにして数字と演算子を区別すればいいのでしょうか?
入力が文字列であると仮定した場合ですが、一文字目から順に見ていって、普通にswitchかifで比較・処理するのではダメなのでしょうか?
たとえば、
char* input = "1234+*+";
ならforつかって
if (input[i] >= '0' && input[i] <= '9') { 数値の処理 }
else if (input[i] == '*') { 掛け算の処理 }
(以下略)
あるいは
switch (input[i]) {
case '0': case'1': ... case'9': 数値の処理
case '*': 掛け算の処理
(以下略)
}
という感じで比べられます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.netでDLLを読み込んで実行す...
-
printf / sprintf のスタック消...
-
Visual C++ 2008 オーバーフロ...
-
スタック領域変更
-
逆ポーランド記法
-
C言語・スタックを使用した逆...
-
プログラムの規模を表す単位「k...
-
個人が特定の人に対して自分の...
-
サンプル文章が長文のタイプ練...
-
ライン数とステップ数の違いに...
-
同じサブネットに属するIPアドレス
-
パソコンでインターネット接続...
-
ubuntuで デイスク/deb/loopと...
-
磁気ディスクのアクセス時間の...
-
MOの容量って、どうなってい...
-
社内LANのネットワークトラフィ...
-
VB6.0で #の意味
-
ネットワークアドレスについて
-
サブネットマスクが255.255.255...
-
AUTO-MDIX機能の無効化
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
最大スタックサイズを大きくす...
-
gccでスタックサイズを変更する...
-
VB.netでDLLを読み込んで実行す...
-
printf / sprintf のスタック消...
-
スタックフレームの消滅
-
H8マイコン スタック領域に...
-
ハイパーカード
-
関数のプロローグとエピローグ...
-
スタック領域変更
-
再帰処理を非再帰処理に書き換...
-
WINAPについて
-
無償Borland5.51でスタックメモ...
-
_CRTIMPの意味は?
-
エラーメッセージが・・・
-
プログラミングについての質問...
-
OCXからのコールバックを繰り返...
-
スタックとキューの使い所
-
マス目上の移動のアルゴリズム
-
WINDOWSなどのOSを構成している...
-
エラー?メッセージ
おすすめ情報