玩慈利网 发表于 2024-7-24 10:52:41

PHP:用0-9共10个数字凑成四则运算式,每个数有且仅出现1次


  近日,在网上看到一个编程题,就是用0-9共10个数字,凑成一个四则运算的等式,整个等式里面,这10个数字有且仅出现一次。四则运算加减乘除都可以。实际上加减本质上是一样的,乘除也是一样的,只需要调换一个位置即可。
  那如何做呢?最笨的办法就是搞循环,然后提取整个等式里面的数字,检测数字是否有重复,当有10个数字,且不重复的时候,那么这个等式就符合要求了。为了方便测试,这里用PHP实现:<?php
/**
* 检查数组中是否存在相同的数字。
*
* @param array $a 输入的数组。
* @return bool 如果存在相同的数字则返回true,否则返回false。
*/
function have_same_number($a)
{
    for ($i = 0; $i < count($a); $i++) {
      for ($j = $i + 1; $j < count($a); $j++) {
            if ($a[$i] == $a[$j]) {
                return true;
            }
      }
    }
    return false;
}

/**
* 将字符串转换为字符数组。
*
* @param string $str 输入的字符串。
* @return array 返回包含字符串中每个字符的数组。
*/
function str_to_array($str)
{
    $arr = [];
    for ($i = 0; $i < strlen($str); $i++) {
      $arr[] = $str[$i];
    }
    return $arr;
}

$zongshu = 0; // 总计数,用于记录满足条件的乘法结果数量
$start_time = microtime(true); // 记录开始时间,用于计算执行耗时

// 大循环遍历所有可能的乘法操作
for ($a = 0; $a < 10000; $a++) {
    for ($b = 0; $b < 10000; $b++) {
      $c = $a * $b; // 计算乘法结果
      $d = strval($a) . strval($b) . strval($c); // 将乘法操作数和结果转换为字符串并拼接

      // 检查拼接后的字符串中是否包含重复的数字
      if (!have_same_number(str_to_array($d))) {
            continue; // 如果包含重复数字,则跳过当前循环
      }

      // 检查结果字符串的长度是否小于10,如果是,则跳过当前循环
      if (strlen($d) < 10) {
            continue;
      }

      // 如果结果字符串长度大于10,则结束当前循环
      if (strlen($d) > 10) {
            break;
      } else {
            echo "{$a} * {$b} = {$c}\n"; // 输出满足条件的乘法表达式
            $zongshu += 1; // 增加总计数
      }
    }
}
echo "计算完毕,总共有{$zongshu}组,耗时:" . (microtime(true) - $start_time) . "秒"; // 输出总计数和执行耗时
?>
代码里面只展示了乘法运算,加法的自己改一下即可。最终的运行结果如下:
附上python代码,与php相比慢了几秒,总体感觉执行时间差不多。
# 导入time模块以获取当前时间
import time

def have_same_number(a):
    """检查数组中是否存在相同的数字。"""
    # 将数组转换为集合,自动去除重复元素
    unique_elements = set(a)
    # 比较原数组长度和集合长度,如果不相等,则说明有重复元素
    return len(a) != len(unique_elements)

def str_to_array(str):
    """将字符串转换为字符列表。"""
    return list(str)

zongshu = 0# 总计数,用于记录满足条件的乘法结果数量
start_time = time.time()# 记录开始时间,用于计算执行耗时

# 大循环遍历所有可能的乘法操作
for a in range(10000):
    for b in range(10000):
      c = a * b# 计算乘法结果
      d = str(a) + str(b) + str(c)# 将乘法操作数和结果转换为字符串并拼接

      # 检查拼接后的字符串中是否包含重复的数字
      if not have_same_number(str_to_array(d)):
            # 检查结果字符串的长度是否等于10
            if len(d) == 10:
                print(f"{a} * {b} = {c}")# 输出满足条件的乘法表达式
                zongshu += 1# 增加总计数
            else:
                if len(d) > 10:
                  break
                continue

# 注意:原PHP代码中对于长度大于10的处理(break)在Python版本中是不必要的,
# 因为我们只关心长度为10的字符串。

print(f"计算完毕,总共有{zongshu}组,耗时:{time.time() - start_time}秒")# 输出总计数和执行耗时
再附一段delphi12编译通过的代码,发现效率惊人,整个算完只用了127毫秒!

program Project1;

{$APPTYPE CONSOLE}

uses
SysUtils, StrUtils;

// 检查数组中是否存在相同的数字
function HaveSameNumber(const a: TArray<Integer>): Boolean;
var
i, j: Integer;
begin
for i := Low(a) to High(a) - 1 do
    for j := i + 1 to High(a) do
      if a = a then
      Exit(True);
Result := False;
end;

// 将字符串转换为字符数组
function StrToArray(const str: string): TArray<Integer>;
var
i: Integer;
begin
SetLength(Result, Length(str));
for i := 0 to Length(str) - 1 do
    Result := StrToInt(str);
end;

var
zongshu: Integer;
startTime: TDateTime;
a, b, c: Integer;
d: string;
charArray: TArray<Integer>;

begin
zongshu := 0;
startTime := Now;
// 大循环遍历所有可能的乘法操作
for a := 0 to 9999 do
    for b := 0 to 9999 do
    begin
      c := a * b;
      d := IntToStr(a) + IntToStr(b) + IntToStr(c);
      if Length(d) < 10 then
          Continue;
      if Length(d) > 10 then
          Break;
      charArray := StrToArray(d);
      if not HaveSameNumber(charArray) then
      begin
      WriteLn(Format('%d * %d = %d', ));
      Inc(zongshu);
      end;
    end;
// 输出总计数和执行耗时
WriteLn('计算完毕,总共有' + IntToStr(zongshu) + '组,耗时:' + FormatDateTime('hh:nn:ss.zzz', Now - startTime));
ReadLn;
end.
页: [1]
查看完整版本: PHP:用0-9共10个数字凑成四则运算式,每个数有且仅出现1次