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

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

新規登録して質問してみよう
ただいま回答率
85.35%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1485閲覧

区間を分割するアルゴリズム

encho

総合スコア182

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/01/09 03:53

編集2021/01/09 03:58

区間を分割するアルゴリズム

区間を分割して数え上げをするときの実装について質問があります。

AtCoderABC033_C
こちらの問題です。

次のような制約を満たす数式

Sが与えられます。
演算子は + (加算) と * (乗算) のみからなる。乗算を優先して計算する。括弧は存在しない。それぞれの項は、 1桁の整数である。
例えば、1+340 、 1+2+3+4+5 などの数式はこの条件を満たしますが、12+3+5、467-3、(3+4)*5+2 のような数式は 条件を満たさないため、入力として与えられません。
あなたは、この数式のうち数字の部分をいくつか選んで 0 に書き換えることで、この式の値を 0にしたいです。式の値を 0にするために 0 に書き換えなければならない数字の個数の最小値を求めてください。

問題の実装方針としては +の数の数え上げと+で囲まれた区間内に0が存在すればそれを数えて次の区間へ移動するということです。

私の実装

こちらの実装で問題は解けます。

C++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 string s; 6 cin >> s; 7 int p_cnt = 1, zero_cnt = 0; 8 9 for(int i=0; i<s.size(); i++) { 10 if(s[i] == '+') p_cnt++; // +の数を数え上げ 11 12 // 区間内に0があればwhile文でインクリメントして次の区間に移動 13 if(s[i] == '0') { 14 zero_cnt++; 15 while(s[i+1] != '+' && i+1 < s.size()) { 16 i++; 17 } 18 } 19 } 20 cout << p_cnt - zero_cnt << endl; 21}

質問

区間を区切って、次の区間に移動する際のwhileの実装は他にどのようなものが考えられるでしょうか?
私の実装だとwhile(s[i+1] != '+' && i+1 < s.size())でプラスの前までindexを増やし、for文の判定でもう一度インクリメントするというのは、少々わかりにくいコードになってしまっているような気がします。
こっちのコードの方が良い。または、他にも実装がありましたら教えていただきたいです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

'+' で切り分けるのは std::getline でできます。
'0' を含むかどうかは string::find で分かります。

C++

1#include <iostream> // cin, cout, endl 2#include <sstream> // istringstream, getline 3using namespace std; 4 5int main() 6{ 7 string s, t; 8 cin >> s; 9 istringstream iss(s); 10 int k = 0; 11 while (getline(iss, t, '+')) 12 if (t.find('0') == string::npos) k++; 13 cout << k << endl; 14}

追記
string::getline と書いていましたが、
getline は string のメンバ関数ではないので、std:: に修正しました。
<string> を include していませんが、<sstream> が string を使うので
その中で include されているものと思われます。

投稿2021/01/09 12:18

編集2021/01/10 07:22
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2021/01/09 15:56

こっちの方が綺麗ですね、高評価。
guest

0

'+' を区切り文字として切り分けたいなら、コレがヒントになるかしら。

C

1#include <stdio.h> 2#include <string.h> 3 4void split(const char* str) { 5 char* s = strdup(str); 6 char* token; 7 for ( token = strtok(s, "+"); token; token = strtok(NULL, "+") ) { 8 printf("[%s] ", token); 9 } 10 printf("\n"); 11 free(s); 12} 13int main() { 14 split("1+3*4*0"); 15 split("1+2+3+4+5"); 16 split("1*2+3*4+5*6*7"); 17 return 0; 18}

実行結果:

[1] [3*4*0] [1] [2] [3] [4] [5] [1*2] [3*4] [5*6*7]

投稿2021/01/09 05:06

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問