LoginSignup
9
7

More than 3 years have passed since last update.

'0'を引くと、charが表す数値を取得できる

Last updated at Posted at 2020-08-23

競技プログラミングで、「これは何をしているのだ?」と思い検索をかけたのですが、あまりヒットしなかったのでメモとして残しておきます。

問題はこちら

問題文
整数 N が 9 の倍数であることと、N を十進法で表したときの各桁の数の和が 9 の倍数であることは同値です。
N が 9 の倍数であるか判定してください。

制約
0≤N<10^200000
N は整数

解法

解法は、問題文を読んで分かる通り、以下の3ステップで解決できそうです。

1. 入力された数値を文字列として取得
2. ループを回して各位の数値を合計する。
3. 合計を9で割って、余りが0なら"Yes", それ以外なら"False"

ASCIIコードに注意

ASCIIコードとは、「文字」と「文字に割り当てられた番号」の対応表のことをいいます。
ASCIIコードとは、「文字」と「文字に割り当てられた番号」の対応表のひとつです。

参考
ASCIIコード表

例えばchar型の'9'はint型では57と同値になります。これでは、期待している値を取得できませんね。。

そこで、char型の'9'をint型の9として扱いたいため、char型の'0'を引いてあげます。'0'はASCIIコードで48を示すので、57-48=9でint型の9が取得できます。

回答例

#include <bits/stdc++.h>
using namespace std;
int main()
{

  int sum = 0;
  // ステップ1. string型で値を受け取る
  string s;
  cin >> s;

  // ステップ2. stringの文字数の数だけループを回す。
  for (int i = 0; i < s.length(); ++i)
  {
    sum += (s[i] - '0'); // ASCIIコードであるため、'0'を引くことで正しい数値を取得できる
  }

  // ステップ3. 9の倍数か判定する
  if (sum % 9 == 0) 
  {
    cout << "Yes" << endl;
  }
  else
  {
    cout << "No" << endl; 
  }

  return 0;
}

前述した通り、ASCIIコードは、「文字」と「文字に割り当てられた番号」の対応表ひとつです。
よって、ASCIIじゃない文字セットが使われてエンコードされている可能性があります。

しかし、C/C++規格書では 0 から 9 の文字に対応する数値が連続することは保証されています。よって、char型の'0'を引いてあげる方法がで、charが表す数値を取得できることは保証されます。

参考
https://qiita.com/yumetodo/items/600ca0df422010cbc4c1#comment-20f4865bca2c3c72070d

9
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7