teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

4

strtol使用

2021/10/27 10:56

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -7,14 +7,6 @@
7
7
 
8
8
  regex_t preg[3];
9
9
 
10
- int getValue(char *f, int so, int eo) {
11
- char backup = f[eo];
12
- f[eo] = '\0';
13
- int v = atoi(&f[so]);
14
- f[eo] = backup;
15
- return v;
16
- }
17
-
18
10
  void replace(char *f, int so, int eo, int v) {
19
11
  sprintf(&f[so], "%d", v);
20
12
  strcat(f, &f[eo]);
@@ -30,15 +22,15 @@
30
22
  }
31
23
  // *
32
24
  while(!regexec(&preg[1], f, 3, match, 0)) {
33
- int v1 = getValue(f, match[1].rm_so, match[1].rm_eo);
25
+ int v1 = (int)strtol(&f[match[1].rm_so], NULL, 10);
34
- int v2 = getValue(f, match[2].rm_so, match[2].rm_eo);
26
+ int v2 = (int)strtol(&f[match[2].rm_so], NULL, 10);
35
27
  int v = v1 * v2;
36
28
  replace(f, match[0].rm_so, match[0].rm_eo, v);
37
29
  }
38
30
  // +
39
31
  while(!regexec(&preg[2], f, 3, match, 0)) {
40
- int v1 = getValue(f, match[1].rm_so, match[1].rm_eo);
32
+ int v1 = (int)strtol(&f[match[1].rm_so], NULL, 10);
41
- int v2 = getValue(f, match[2].rm_so, match[2].rm_eo);
33
+ int v2 = (int)strtol(&f[match[2].rm_so], NULL, 10);
42
34
  int v = v1 + v2;
43
35
  replace(f, match[0].rm_so, match[0].rm_eo, v);
44
36
  }
@@ -221,7 +213,6 @@
221
213
  test("1+3*(2+4)");
222
214
  }
223
215
  ```
224
- 実行
225
216
  ```plain
226
217
  1 + 2
227
218
  1 2 +

3

正規表現修正

2021/10/27 10:56

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -48,7 +48,7 @@
48
48
  void test(char *formula) {
49
49
  printf("f=%s\n", formula);
50
50
 
51
- regcomp(&preg[0], "\(.+\)", REG_EXTENDED|REG_NEWLINE); // ()
51
+ regcomp(&preg[0], "\([^(]+\)", REG_EXTENDED|REG_NEWLINE); // ()
52
52
  regcomp(&preg[1], "([0-9]+)\*([0-9]+)", REG_EXTENDED|REG_NEWLINE); // *
53
53
  regcomp(&preg[2], "([0-9]+)\+([0-9]+)", REG_EXTENDED|REG_NEWLINE); // +
54
54
 

2

正規表現コード追加

2021/10/27 10:41

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -1,5 +1,92 @@
1
+ 正規表現を使えばこうなるでしょう。
2
+ ```c
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <regex.h>
7
+
8
+ regex_t preg[3];
9
+
10
+ int getValue(char *f, int so, int eo) {
11
+ char backup = f[eo];
12
+ f[eo] = '\0';
13
+ int v = atoi(&f[so]);
14
+ f[eo] = backup;
15
+ return v;
16
+ }
17
+
18
+ void replace(char *f, int so, int eo, int v) {
19
+ sprintf(&f[so], "%d", v);
20
+ strcat(f, &f[eo]);
21
+ }
22
+
23
+ int calc(char *f) {
24
+ regmatch_t match[3];
25
+ // ()
26
+ while(!regexec(&preg[0], f, 1, match, 0)) {
27
+ f[(int)match[0].rm_eo-1] = '\0';
28
+ int v = calc(&f[match[0].rm_so+1]);
29
+ replace(f, match[0].rm_so, match[0].rm_eo, v);
30
+ }
31
+ // *
32
+ while(!regexec(&preg[1], f, 3, match, 0)) {
33
+ int v1 = getValue(f, match[1].rm_so, match[1].rm_eo);
34
+ int v2 = getValue(f, match[2].rm_so, match[2].rm_eo);
35
+ int v = v1 * v2;
36
+ replace(f, match[0].rm_so, match[0].rm_eo, v);
37
+ }
38
+ // +
39
+ while(!regexec(&preg[2], f, 3, match, 0)) {
40
+ int v1 = getValue(f, match[1].rm_so, match[1].rm_eo);
41
+ int v2 = getValue(f, match[2].rm_so, match[2].rm_eo);
42
+ int v = v1 + v2;
43
+ replace(f, match[0].rm_so, match[0].rm_eo, v);
44
+ }
45
+ return atoi(f);
46
+ }
47
+
48
+ void test(char *formula) {
49
+ printf("f=%s\n", formula);
50
+
51
+ regcomp(&preg[0], "\(.+\)", REG_EXTENDED|REG_NEWLINE); // ()
52
+ regcomp(&preg[1], "([0-9]+)\*([0-9]+)", REG_EXTENDED|REG_NEWLINE); // *
53
+ regcomp(&preg[2], "([0-9]+)\+([0-9]+)", REG_EXTENDED|REG_NEWLINE); // +
54
+
55
+ char *f = malloc(strlen(formula)+1);
56
+ strcpy(f, formula);
57
+
58
+ int a = calc(f);
59
+ printf("a=%d\n", a);
60
+
61
+ free(f);
62
+
63
+ regfree(&preg[2]);
64
+ regfree(&preg[1]);
65
+ regfree(&preg[0]);
66
+ }
67
+
68
+ int main(int argc, char *argv[]) {
69
+ test("1+2");
70
+ test("2*3");
71
+ test("1+2*3");
72
+ test("(1+2)*3");
73
+ test("1+3*(2+4)");
74
+ }
75
+ ```
76
+ ```plain
77
+ f=1+2
78
+ a=3
79
+ f=2*3
80
+ a=6
81
+ f=1+2*3
82
+ a=7
83
+ f=(1+2)*3
84
+ a=9
85
+ f=1+3*(2+4)
86
+ a=19
87
+ ```
88
+
1
89
  参考までに、スタックでベタに逆ポーランド記法利用時はこんな感じかと。
2
-
3
90
  ```c
4
91
  #include <stdio.h>
5
92
  #include <stdlib.h>

1

説明追加

2021/10/27 10:37

投稿

jimbe
jimbe

スコア13357

answer CHANGED
@@ -1,4 +1,4 @@
1
- 参考までに、逆ポーランド記法利用時はこんな感じかと。
1
+ 参考までに、スタックでベタに逆ポーランド記法利用時はこんな感じかと。
2
2
 
3
3
  ```c
4
4
  #include <stdio.h>