kron matlab_kron的实战例子: 寻找最大的回文乘积

08db290229968fa4583268892d0074ad.png

关于kron, 我写过另一篇文章, 读者可以看一下, 熟悉一下kron的用法:

菡姐:使用kron来实现repmat, repelem的功能​zhuanlan.zhihu.com
a0f7a21b10f8e80db477810d2f3a3fbf.png

题目的链接:

Project Euler: Problem 4, Palindromic numbers​ww2.mathworks.cn

题目描述:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of numbers less than or equal to the input number.
Thank you to Project Euler Problem 4

意思很简单, 寻找一定范围内的两个数的乘积, 必须是回文数, 并且是最大的.

用数学语言表达大概就是:

max c = a*b
std:
1 <= a <= x
1 <= b <= x
c is palindromic number

回文数的定义是: 左右颠倒过来, 很原先一模一样, 即左右对称, 就像这篇文章的封面图一样.

先看我写的代码, 没有对比就没有伤害 o(╥﹏╥)o :

function ans = euler004(x)
v = x-99:x; % 这是v = 1:x的变形, 提高了搜索的下限, 目的为了节省内存和运算量.
M = unique(v'*v); % 利用矩阵乘法, 生成了乘积矩阵, 然后用unique去重, 以及压缩成向量
strM = string(M); % 变成string型, 目的是方便进行左右颠倒
M(find(reverse(strM) == strM, 1, 'last')); % 检验左右对称性
end

代码有注释, 就不多做解释了.

然后是最佳代码(size最小, 并且不是作弊代码, 比如使用regexp或者直接插入答案的)

function y = euler004(x)
for y = sort(kron(1:x,1:x),'descend')
    if isequal(int2str(y),flip(int2str(y)))
        return
    end
end

分析:

1 使用了kron来构造"乘积向量".

这个是最大的亮点:

因为一般思路是利用矩阵乘法或者bsxfun来构造"乘积矩阵".

乘积向量相比乘积矩阵的优势是: 乘积矩阵在排序之前必须变形成向量, 多了一个步骤, 而kron直接就生成了向量, 相比之下, 少了一个步骤.

2 第二个亮点是for循环里面, 直接使用了该"乘积向量", 而不是在for循环里面生成索引.

for循环里面直接使用向量的做法, 相对来说是比较冷门技巧, 很多使用MATLAB多年的人都不知道.

举个例子说明:

例子1, 当V为行向量时, for循环每次取其中一个元素(标量).

V = [2, 5, 1.3];
cnt = 0;
for v = V
    cnt = cnt + 1;
    v
end
cnt

运行结果:

v =
     2
v =
     5
v =
                       1.3
cnt =
     3

可以看到, 每次取一个元素, 并且循环了3次.

例子2, 当V为列向量时:

V = [2;5;1.3];
cnt = 0;
for v = V
    cnt = cnt + 1;
    v
end
cnt

运行结果:

v =
                         2
                         5
                       1.3
cnt =
     1

运行结果与很多人预期的不同, 直接取了整个列向量, 因此, 也只需要循环一次.

例子3, 当V为矩阵时:

V = [1, 2;3, 4];
cnt = 0;
for v = V
    cnt = cnt + 1;
    v
end
cnt

运行结果:

v =
     1
     3
v =
     2
     4
cnt =
     2

每次取其中一列, 有多少列就循环多少次.

从这三个例子中不难总结出规律:

MATLAB的for循环是以列为单位的.

3 使用了isequal来比较字符串.

也可以使用strcmp来比较字符串.

相比strcmp, isequal的使用范围更广.

4 使用了int2str, 也可以使用num2str

两者在整数情况下, 效果一样, 在有小数的情况下, int2str会先取整.

>> num2str(134)
ans =
    '134'
>> int2str(134)
ans =
    '134'
>> int2str(134.4)
ans =
    '134'
>> num2str(134.4)
ans =
    '134.4'
>> int2str(-134.4)
num2str(-134.4)
ans =
    '-134'
ans =
    '-134.4'
>> int2str(134.9)
num2str(134.9)
ans =
    '135'
ans =
    '134.9'
>> int2str(-134.9)
num2str(-134.9)
ans =
    '-135'
ans =
    '-134.9'

取整的方法明显为round.

这是MATLAB文档里面的解释:

chr = int2str(N) treats N as a matrix of integers and converts it to a character array that represents the integers. If N contains floating-point values, int2str rounds them before conversion.

创作不易, 请大家"素质三连": 点赞, 收藏, 分享.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值