题解 | #四则运算#
四则运算
http://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
<?php
class Scanner {
/** @var resource */
protected $in;
/**
* Scanner constructor.
* @param $uri "php://input", "file:///D:/Users/mingz/CLionProjects/nowcoder/huawei/core.txt"
*/
public function __construct(/* string */$uri = "php://stdin") {
$this->in = fopen($uri, 'r');
}
private static function isBlank($c) {
return strncmp($c, " ", 1) == 0 || strncmp($c, "\t", 1) == 0
|| strncmp($c, "\r", 1) == 0 || strncmp($c, "\n", 1) == 0;
}
/**
* Get a word from resource $this->in, char by char
* @return string
*/
private function getWord() {
$ch = fgetc($this->in);
for (; !feof($this->in); $ch = fgetc($this->in)) {
if (!self::isBlank($ch)) {break;}
}
// $at = ftell($this->in);
$word = "";
for (; !feof($this->in); ) {
if (self::isBlank($ch)) {
break;
} else {
$word .= $ch;
}
$ch = fgetc($this->in);
}
return $word;
}
private static function atoi($s) {
$num = 0;
$i = 0;
for (; isset($s[$i]); $i += 1) {
if (!self::isBlank($s[$i])) {break;}
}
$codeMinus = ord("-");
$negative = false;
if (ord($s[$i]) == $codeMinus) {
$negative = true;
$i += 1;
}
$codeDot = ord(".");
for (; isset($s[$i]); $i += 1) {
$code = ord($s[$i]);
if (48 <= $code && $code < 58) {
$num = 10 * $num + ($code - 48);
} elseif ($code == $codeDot) {
break;
}
if ($num > PHP_INT_MAX) {
throw new OutOfRangeException("Integer out of range: ".PHP_INT_MAX);
}
}
if ($negative) {$num = 0 - $num;}
return $num;
}
public function nextInt() {
$nextWord = "";
for (;;) {
$nextWord = $this->getWord();
if (is_numeric($nextWord)) {break;}
}
return self::atoi($nextWord);
}
public function nextLine() {
$line = fgets($this->in);
return rtrim($line, "\r\n");
}
public function next() {return $this->getWord();}
public function hasNext() {
if (feof($this->in)) {
return false;
}
$pos = ftell($this->in);
$bytesRead = fread($this->in, 2);
if (false == $bytesRead) {
return false;
}
fseek($this->in, $pos);
return !empty(rtrim($bytesRead, "\r\n"));
}
public function __destruct() {fclose($this->in);}
}
class HJ50
{
const ORD_0 = 48;
private static function isdigit($c): bool {
$code = ord($c[0]);
return 48 <= $code && $code < 58;
}
private static function isOpenBrace($c) :bool {
return $c == '{' || $c == '[' || $c == '(';
}
private static function isCloseBrace($c) : bool {
return $c == '}' || $c == ']' || $c == ')';
}
/**
* @param $data string
* @param $len int
* @param $pos int
* @return int
*/
private static function _compute(string $data, int $len, int &$pos): int
{
$num = 0;
$op = '+';
$st = array(); // stack
while ($pos < $len) {
if (self::isOpenBrace($data[$pos])) {
$pos += 1;
$num = self::_compute($data, $len, $pos);
}
while ($pos < $len && self::isdigit($data[$pos])) {
$num = $num * 10 + ord($data[$pos]) - self::ORD_0;
$pos += 1;
}
switch ($op) {
case '+': array_push($st, $num); break;
case '-': array_push($st, -$num); break;
case '*':
$tmp = array_pop($st);
$tmp *= $num;
array_push($st, $tmp);
break;
case '/':
$tmp = array_pop($st);
$tmp = floor($tmp / $num);
array_push($st, $tmp);
break;
default:
}
$num = 0;
$op = $data[$pos];
if (self::isCloseBrace($data[$pos])) {
$pos += 1;
break;
}
$pos += 1;
}
$sum = 0;
while (!empty($st)) {
$sum += array_pop($st);
}
return $sum;
}
/**
* @param $data
* @return int
*/
public function compute($data): int
{
$pos = 0;
return self::_compute($data, strlen($data), $pos);
}
}
class Solution {
public static function main() {
$sc = new Scanner("php://stdin");
// $sc = new Scanner("./input/input.txt");
$solution = new HJ50();
while ($sc->hasNext()) {
$line = $sc->nextLine();
printf("%s\n", $solution->compute($line));
}
}
}

