简体   繁体   English

matlab中的大号Palindroms

[英]Large Number Palindroms in matlab

Converting a number into string and reversing that string and then comparing if the both strings are equal or not. 将数字转换为字符串并反转该字符串,然后比较两个字符串是否相等。

I am using the above mentioned algorithms to find out Palindromes. 我正在使用上面提到的算法来找出Palindromes。

The problem is, I want to detect the number of palindromes from 10^50 to 10^100, and this function is taking too much time. 问题是,我想检测从10 ^ 50到10 ^ 100的回文数量,这个功能需要花费太多时间。

Any faster algorithm or hint to do this? 有没有更快的算法或提示呢?

I think you need to take a more "combinatoric" approach to this. 我认为你需要对此采取更“组合”的方法。 Rather than brute-forcing through all those numbers (it probably can't be done with today's computing power...), think about it in steps: 而不是强行通过所有这些数字(它可能无法用今天的计算能力完成......),请按步骤思考:

Given the number of digits, how many possible combinations can be palindromes? 给定数字位数,可以将多少种可能的组合作为回文?

Well, to begin with, we can start looking at numbers with quite few digits, to get a sense of how it works: 好吧,首先,我们可以开始查看数字很少的数字,以了解它的工作原理:

  • For 2-digit numbers, if you choose the first digit the second has to be the same if the number is to be palindromic. 对于2位数字,如果您选择第一个数字,则第二个数字必须相同,如果数字是回文数字。 That is, in base 10 you have 10 choices (if you count 00 as two-digit) or 9 choices (if you don't, which makes more sense). 也就是说,在10中你有10个选择(如果你把00算作两位数)或9个选择(如果你没有,那就更有意义)。

  • For 3-digit numbers, if you choose the first digit the third is fixed. 对于3位数字,如果选择第一个数字,则第三个数字是固定的。 That gives you 9 choices (as we don't call eg 020 three-digit). 这给你9个选择(因为我们不称之为例如020三位数)。 The middle digit is still free, so that gives you another 10 (since the middle digit can be 0) independent choices. 中间数字仍然是空闲的,因此可以为您提供另外10个(因为中间数字可以为0)独立选择。 The total number of palindromes is given by 9*10 = 90. 回文总数由9 * 10 = 90给出。

  • For 4-digit numbers, you can choose the first and second digit independently, and then the third and fourth are fixed. 对于4位数字,您可以单独选择第一个和第二个数字,然后固定第三个和第四个数字。 The first must be nonzero, but after that zeroes are OK. 第一个必须是非零的,但在那之后零可以。 9*10 = 90 palindromes. 9 * 10 = 90个回文。

  • For 5-digit numbers, you choose first, second and third independently, and then the fourth and fifth are fixed. 对于5位数字,您可以单独选择第一个,第二个和第三个,然后修复第四个和第五个。 The first is nonzero, the rest are completely free: 9*10^2 = 900 palindromes. 第一个是非零,其余是完全免费的:9 * 10 ^ 2 = 900个回文。

I think we're ready to generalize this, don't you? 我想我们已经准备好推广这个,不是吗?

A general approach 一般方法

We noted above that for even digit numbers, you can choose digits for half the number independently, and for odd digit numbers you also choose the middle digit. 我们在上面指出,对于偶数位数,您可以单独选择数字的一半 ,对于奇数位数字,您也可以选择中间数字。 The first digit cannot be 0, but all the others can, yielding. 一个数字不能为0,但所有其他数字都可以,屈服。 That means that for a number with N digits, the number of palindrome choices are 这意味着对于具有N位数的数字,回文选择的数量是
P = 10 * 9 ceil( N / 2 )-1 . P = 10 * 9 ceil( N / 2 )-1 Note that for this to work, N / 2 must be floating point division - for N = 7 we want 3.5, so we can round it up to 4 and choose also the middle digit. 注意,为了使其工作, N / 2必须是浮点除法 - 对于N = 7我们想要3.5,所以我们可以将它四舍五入并选择中间数字。

The specific problem 具体问题

To count the number of palindromes between 10^50 and 10^100, there is one more bit of information we need to make use of: what we know about the number of digits for these numbers. 为了计算10 ^ 50到10 ^ 100之间的回文数量,我们需要使用的信息还有一点:我们知道这些数字的位数。 Since all numbers between 10 50 and 10 51 have 50 digits (and since 10 100 is not a palindrome) the rest is quite simple. 由于10 50到10 51之间的所有数字都有50位数(并且因为10 100不是回文),其余数字非常简单。

A python snippet that gives you the count: 一个python片段,为您提供计数:

import math

palindromes = 0
for n in range(50):
    palindromes = palindromes + 10**math.ceil((n+50)/2.0)*0.9

Or, with a one-liner that does exactly the same thing: 或者,使用一行完成同样的事情:

import math
sum(.9*10**math.ceil((n+50)/2.0) for n in range(50))

Since this loops over 50 iterations, rather than almost 10 100 , it's no problem at all for any computer. 由于这循环超过50次迭代,而不是几乎10 100次 ,因此任何计算机都没有问题。 Note also that 9*10 N-1 = 0.9*10 N . 还要注意9 * 10 N-1 = 0.9 * 10 N.

How many k digit palindromes are there? 有多少k个数字的回文? Ok, now, how many k+2 digit palindromes are there? 好的,现在,有多少k + 2位数的回文? See that we can write a recursion for the number of palindromes. 看看我们可以为回文数写一个递归。

Define P(n) to be the number of n digit palindromes. 将P(n)定义为n位数的回文数。 Arbitrarily, assume that there is only one 0 digit palindrome, so P(0) = 1. 任意地,假设只有一个0位数的回文,所以P(0)= 1。

As well, it seems logical to state that there are 9 one digit palindromes, so P(1) = 9. And P(2) is also 9, since the two digit palindromes are easy to build and count. 同样,似乎合乎逻辑地说有9个一位数的回文,因此P(1)= 9.而P(2)也是9,因为两位数的回文很容易建立和计数。

Can we generate the 3 digit palindromes? 我们能生成3位数的回文吗? We will do so by appending/prepending any non-zero digit to all of the 1 digit palindromes. 我们将通过在所有1位数的回文中附加/前置任何非零数字来实现。 That misses the palindromes of form x0x, so we will add them in too. 这错过了x0x形式的回文,所以我们也会添加它们。

P(3) = P(1)*9 + 1*9 = (P(1) + 1)*9

How about 5 digit palindromes? 5位数的回文怎么样? Again, append & prepend any non-zero digit to the smaller order palindromes. 再次,将任何非零数字附加并附加到较小的订单回文。 But we need to worry about the case where we need zeros inside the palindrome. 但我们需要担心我们在回文区内需要零的情况。 So x0p0x is a palindrome, as well as x000x. 所以x0p0x是一个回文,以及x000x。

P(5) = P(3)*9 + P(1)*9 + 1*9 = (P(3) + P(1) + 1)*9

(We can go one step further, and write P(5) in terms of P(1).) (我们可以更进一步,用P(1)写出P(5)。)

So we have P(5) = 900. A good idea is always to verify simple claims like this. 所以我们得到P(5)= 900.一个好主意总是验证像这样的简单索赔。 This makes us more confident that we have not missed anything. 这使我们更加自信,我们没有错过任何东西。 I'll do that in MATLAB. 我会在MATLAB中做到这一点。

n = 10000:99999;
D = dec2base(n,10);
isp = sum(all(D == fliplr(D),2))

isp =
   900

We can extrapolate the above logic to compute the 7 digit palindromes, resulting in the formula: 我们可以推断上述逻辑来计算7位数的回文,得到公式:

P(7) = P(5)*9 + P(3)*9 + P(1)*9 + 1*9 = (P(5) + P(3) + P(1) + 1)*9

This suggests that P(7) = 9000. Again, we can test that claim using brute force. 这表明P(7)= 9000.同样,我们可以使用强力来测试该声明。

n = 1000000:9999999;
D = dec2base(n,10);
isp = sum(all(D == fliplr(D),2))
isp =

        9000

So it seems easy to count the n digit palindromes when n is odd. 因此,当n为奇数时,似乎很容易计算n位数的回文数。 It is just as easy to count the n digit palindromes for even n. 即使n也可以很容易地计算n位数的回文数。 I'll let you derive those relations. 我会让你得出那些关系。

Because the palindrome property of a number depends essentially on the base in which you want to represent the number, you have to convert it to string, in the base that you chose. 因为数字的回文属性主要取决于您想要表示数字的基数,所以您必须在您选择的基数中将其转换为字符串。 There may be specific tricks for specific bases, but in the general case I guess the fastest way would be: 特定基础可能有特定的技巧,但在一般情况下我猜最快的方法是:

% Suppose your number is stored as string in str
strcmp(str, str(end:-1:1))

Later edit: now I see that what are you looking for is not a test for "palindromeness," but to count the palindromes between 2 given numbers. 后来编辑:现在我看到你在找什么不是对“回文”的测试,而是计算两个给定数字之间的回文。 Again, that depends on the base, but you can always count palindromes with 2n or 2n+1 digits in base B by counting the valid numbers having n digits in base B. But this is not about Matlab, I guess it's about math. 同样,这取决于基数,但你总是可以通过计算基数B中有n个数字的有效数字来计算基数B中2n或2n + 1位数的回文。但这不是关于Matlab,我猜它是关于数学的。

Even later edit: maybe this would help (it's not optimal, but I hope is clear and helpful): 甚至稍后编辑:也许这会有所帮助(它不是最佳的,但我希望是清楚和有帮助的):

%COUNT_PALINDROMES returns the number of palindrome
% numbers with nd digits in base b

function np = count_palindromes(b, nd)

        % For the sake of brevity the function assumes
        % that b has natural values greater than 1, and
        % nd has appropriate values also.

        if nd == 1
                % Single digit "palindromes"
                np = b;

        elseif mod(nd,2) == 1
                % 2n+1 digit palindromes
                %    abcd...uvXvu...cba
                n  = fix(nd/2);
                np = (b-1)*b^n;

        else
                % 2n digit palindromes
                %    abcd...uvvu...cba
                n = fix(nd/2);
                np = (b-1)*b^(n-1);
        end;
end

Please be careful to the floating point precision when using its values. 使用其值时请注意浮点精度。 I'm not sure if you'll be able to keep exactly the number of palindromes in a double -- which is the default type in Matlab. 我不确定你是否能够准确地保持双倍的回文数量 - 这是Matlab中的默认类型。 Change to other (integral) types as needed. 根据需要更改为其他(整数)类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM