【问题标题】:What is the logic for solving this sequence? [closed]解决这个序列的逻辑是什么? [关闭]
【发布时间】:2011-04-10 10:48:25
【问题描述】:

顺序是这样的..7,8,77,78,87,88,777,778,787,788等等..

找到序列的第 n 个数字的逻辑是什么?我尝试将其除以 2,然后再除以 4,但它似乎不起作用。

【问题讨论】:

  • 投票关闭它的人:寻找序列的第n个元素的算法是如何跑题的?
  • 如果人们发表评论会很好,但如果我不得不猜测它闻起来像家庭作业,并且要求提供完整的答案而不是提示。
  • @Nikita Rybak:拥有第 n 个元素的算法没有意义。任何序列都可以以任何方式继续。
  • 考虑这个序列:[0, 1, 00, 01, 10, 11, 000, 001, 010, 011]。和你的一样。
  • @Thomas:看起来确实有一定的相似性,但这并不能真正解释关闭的原因。那个序列怎么不值得被问到?

标签: algorithm logic


【解决方案1】:

二进制,从二开始计数,忽略前导数字,使用 7 和 8 表示零和一:

        7,  8,  77,  78,  87,  88,  777,  778,  787,  788
 0, 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011 

【讨论】:

  • +1 表示解决方案。精彩的观察皮特!这是python 2.6实现-for i in range(2,15):print "".join(map((lambda x: ('8','7')[x=='0']), bin( i)[2:])[1:]),
  • 臃肿。这里:for i in range(2,15):print"".join('78'[int(x)]for x in bin(i)[3:]),
【解决方案2】:

观察:

  1. 该序列似乎是一个仅包含数字 7 和 8 的升序数字列表。

  2. 位数不递减,对于每个 n 位数部分,序列中有 2 ** n 个数字。

  3. n位数字的前半部分以7开头,后半部分以8开头。

  4. 对于n位数字的每一半,第一个数字之后的剩余数字与n-1位数字相同。

这些事实可以用来构造一个合理有效的递归实现。

这是一个 C# 实现:

void Main() {
    for (int i = 0; i < 10; i++)
        Console.WriteLine (GetSequence(i));
}

string GetSequence(int idx) {
    if (idx == 0) return "7";
    if (idx == 1) return "8";

    return GetSequence(idx / 2 - 1) + GetSequence(idx % 2);
}

输出:

7
8
77
78
87
88
777
778
787
788

【讨论】:

  • 看来你对递归很着迷.. :)
【解决方案3】:

由于块的大小呈指数增长(长度为 1 的 2 个元素、长度为 2 的 4 个元素、长度为 3 的 8 个元素等),您可以轻松确定结果数中的位数。

    long block_size = 2;
    int len = 1;
    while (n > block_size) {
        n -= block_size;  // n is changed here
        block_size *= 2;
        ++len;
    }

现在,您只需创建 n - 1 的二进制表示,其中 7 表示 0,8 表示 1(用零将其填充到长度 len)。非常简单。

我假设这里的索引从 1 开始。

【讨论】:

  • 让 n=10.. 必须给出 788 作为答案.. 或 011. 但是对于 n=10,n-1 是 9,它给出了 1001.. 的二进制序列。作为 3,我们选择最后三个二进制文件,即 001,这不是答案..!!
  • @vaibhav 注意,我们在循环中也改变了 n。我编辑了答案以强调它。
  • 哦,是的..我的错误..非常感谢..
【解决方案4】:

将 0 替换为 7,将 1 替换为 8,并将其视为二进制序列

【讨论】:

  • 不完全是:7* = 0* 将始终为 0。
【解决方案5】:

用 PHP 编写。我假设序列元素从 1 开始编号。

$n = 45;
// let's find the 45th sequence element.
$length = 1;
while ( $n >= pow(2, $length + 1) - 1 ) {
    $length++;
}
// determine the length in digits of the sequence element
$offset = $n - pow(2, $length) + 1;
// determine how far this sequence element is past the
// first sequence element of this length
$binary = decbin($offset);
// obtain the binary representation of $offset, as a string of 0s and 1s
while ( strlen($binary) < $length ) {
    $binary = '0'.$binary;
}
// left-pad the string with 0s until it is the required length
$answer = str_replace( array('0', '1'),
                       array('7', '8'),
                       $binary
                       );

【讨论】:

  • +1:看起来我们的想法一样。 ;) 您实际上可以通过使用logfloor 函数来避免第一个while 循环。
  • 是的,我考虑过 log() 和 floor(),但我不确定 floor() 是否会因为 php 中的浮点不准确而导致问题。
【解决方案6】:

看起来像一个简单的二进制序列,其中7代表二进制零,8代表二进制1。

【讨论】:

  • 好的.. 那么为什么第三个数字是 77 或者在你的情况下.. 00..??
  • 序列从二进制零重新开始,但使用两位而不是一位。等等。每次序列溢出其数字时,从零重新开始并添加另一个数字。
  • 问题是找到第n个元素,这需要枚举所有元素直到n。
  • @recursive:不是这样。 d = 1; seq = n; while (seq &gt;= 2^d) { seq -= 2^d; ++d; }。您将返回 seq'th d-digit 序列,通过将 0 转换为 7 并将 1 转换为 8,它可以轻松地转换为所需的序列。
【解决方案7】:

您可以直接计算第 N 个数字 (num)无需递归或循环,方法是执行以下操作(示例代码在 MATLAB 中): p>

  • 计算数字的位数:

    nDigits = floor(log2(num+1));
    
  • 在第一次减去一个小于 2 的幂 nDigits 之后,找到数字 num 的二进制表示(只有第一个 nDigits 数字):

    binNum = dec2bin(num-(2^nDigits-1),nDigits);
    
  • 1 和 0 字符串中的每个值加 7:

    result = char(binNum+7);
    

这里做个测试,把上面三个步骤放到一个匿名函数f

>> f = @(n) char(dec2bin(n+1-2^floor(log2(n+1)),floor(log2(n+1)))+7);
>> for n = 1:20, disp(f(n)); end
7
8
77
78
87
88
777
778
787
788
877
878
887
888
7777
7778
7787
7788
7877
7878

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 2023-03-13
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多